Commit 7bf44fe5 authored by Christian Ledermann's avatar Christian Ledermann

move from lists to generators to fetch the contents of a container or kml, use...

move from lists to generators to fetch the contents of a container or kml, use getter and setter for feature.styleUrl
parent f67a7e85
...@@ -19,13 +19,9 @@ This library only implements a subset of Atom that is useful with KML ...@@ -19,13 +19,9 @@ This library only implements a subset of Atom that is useful with KML
import logging import logging
logger = logging.getLogger('fastkml.atom') logger = logging.getLogger('fastkml.atom')
from config import etree
try: NS = '{http://www.w3.org/2005/Atom}'
from lxml import etree
LXML = True
except ImportError:
import xml.etree.ElementTree as etree
LXML = False
import re import re
regex = r"^[a-zA-Z0-9._%-]+@([a-zA-Z0-9-]+\.)*[a-zA-Z]{2,4}$" regex = r"^[a-zA-Z0-9._%-]+@([a-zA-Z0-9-]+\.)*[a-zA-Z]{2,4}$"
...@@ -75,7 +71,7 @@ class Link(object): ...@@ -75,7 +71,7 @@ class Link(object):
def __init__(self, ns=None, href=None, rel=None, type=None, def __init__(self, ns=None, href=None, rel=None, type=None,
hreflang=None, title=None, lenght=None): hreflang=None, title=None, lenght=None):
if ns == None: if ns == None:
self.ns = '{http://www.w3.org/2005/Atom}' self.ns = NS
else: else:
self.ns = ns self.ns = ns
self.href = href self.href = href
...@@ -129,6 +125,7 @@ class _Person(object): ...@@ -129,6 +125,7 @@ class _Person(object):
entity. It has one required element, name, and two optional elements: entity. It has one required element, name, and two optional elements:
uri, email. uri, email.
""" """
__name__ = None
ns = None ns = None
name = None name = None
...@@ -142,7 +139,7 @@ class _Person(object): ...@@ -142,7 +139,7 @@ class _Person(object):
def __init__(self, ns=None, name=None, uri=None, email=None): def __init__(self, ns=None, name=None, uri=None, email=None):
if ns == None: if ns == None:
self.ns = '{http://www.w3.org/2005/Atom}' self.ns = NS
else: else:
self.ns = ns self.ns = ns
self.name = name self.name = name
......
...@@ -35,7 +35,7 @@ class _BaseObject(object): ...@@ -35,7 +35,7 @@ class _BaseObject(object):
if self.targetId: if self.targetId:
element.set('targetId', self.targetId) element.set('targetId', self.targetId)
else: else:
raise NotImplementedError raise NotImplementedError("Call of abstract base class, subclasses implement this!")
return element return element
...@@ -44,9 +44,17 @@ class _BaseObject(object): ...@@ -44,9 +44,17 @@ class _BaseObject(object):
def from_element(self, element): def from_element(self, element):
if self.ns + self.__name__ != element.tag: if self.ns + self.__name__ != element.tag:
raise TypeError raise TypeError("Call of abstract base class, subclasses implement this!")
else: else:
if element.get('id'): if element.get('id'):
self.id = element.get('id') self.id = element.get('id')
if element.get('targetId'): if element.get('targetId'):
self.targetId = element.get('targetId') self.targetId = element.get('targetId')
def to_string(self, prettyprint=True):
""" Return the KML Object as serialized xml """
if config.LXML and prettyprint:
return etree.tostring(self.etree_element(), encoding='utf-8',
pretty_print=True)
else:
return etree.tostring(self.etree_element(), encoding='utf-8')
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""frequently used constants and abstract base classes""" """frequently used constants and abstract base classes"""
try:
from lxml import etree
LXML = True
except ImportError:
import xml.etree.ElementTree as etree
LXML = False
NS = '{http://www.opengis.net/kml/2.2}' NS = '{http://www.opengis.net/kml/2.2}'
...@@ -15,19 +15,19 @@ from geometry import MultiPoint, MultiLineString, MultiPolygon ...@@ -15,19 +15,19 @@ from geometry import MultiPoint, MultiLineString, MultiPolygon
from geometry import LinearRing from geometry import LinearRing
from datetime import datetime, date from datetime import datetime, date
# note that there are some ISO 8601 timeparsers at pypi
# but in my tests all of them had some errors so we rely on the
# tried and tested dateutil here which is more stable. As a side effect
# we can also parse non ISO compliant dateTimes
import dateutil.parser import dateutil.parser
import logging import logging
logger = logging.getLogger('fastkml.kml') logger = logging.getLogger('fastkml.kml')
try:
from lxml import etree
LXML = True
except ImportError:
import xml.etree.ElementTree as etree
LXML = False
import config import config
from config import etree
from base import _BaseObject from base import _BaseObject
from styles import StyleUrl, Style, StyleMap, _StyleSelector from styles import StyleUrl, Style, StyleMap, _StyleSelector
...@@ -80,24 +80,29 @@ class KML(object): ...@@ -80,24 +80,29 @@ class KML(object):
def to_string(self, prettyprint=False): def to_string(self, prettyprint=False):
""" Returm the KML Object as xml """ """ Return the KML Object as serialized xml """
if LXML and prettyprint: if config.LXML and prettyprint:
return etree.tostring(self.etree_element(), encoding='utf-8', return etree.tostring(self.etree_element(), encoding='utf-8',
pretty_print=True) pretty_print=True)
else: else:
return etree.tostring(self.etree_element(), encoding='utf-8') return etree.tostring(self.etree_element(), encoding='utf-8')
def features(self): def features(self):
""" return a list of features """ """ iterate over features """
#XXX yield feature, test if they are valid features for feature in self._features:
return self._features if isinstance(feature, (Document, Folder, Placemark)):
yield feature
else:
raise TypeError(
"Features must be instances of (Document, Folder, Placemark)")
def append(self, kmlobj): def append(self, kmlobj):
""" append a feature """ """ append a feature """
if isinstance(kmlobj, (Document, Folder, Placemark)): if isinstance(kmlobj, (Document, Folder, Placemark)):
self._features.append(kmlobj) self._features.append(kmlobj)
else: else:
raise TypeError raise TypeError(
"Features must be instances of (Document, Folder, Placemark)")
class _Feature(_BaseObject): class _Feature(_BaseObject):
""" """
...@@ -110,6 +115,7 @@ class _Feature(_BaseObject): ...@@ -110,6 +115,7 @@ class _Feature(_BaseObject):
#PhotoOverlay, #PhotoOverlay,
#ScreenOverlay #ScreenOverlay
""" """
name = None
#User-defined text displayed in the 3D viewer as the label for the #User-defined text displayed in the 3D viewer as the label for the
#object (for example, for a Placemark, Folder, or NetworkLink). #object (for example, for a Placemark, Folder, or NetworkLink).
description = None description = None
...@@ -123,7 +129,7 @@ class _Feature(_BaseObject): ...@@ -123,7 +129,7 @@ class _Feature(_BaseObject):
#Boolean value. Specifies whether a Document or Folder appears #Boolean value. Specifies whether a Document or Folder appears
#closed or open when first loaded into the Places panel. #closed or open when first loaded into the Places panel.
#0=collapsed (the default), 1=expanded. #0=collapsed (the default), 1=expanded.
styleUrl = None _styleUrl = None
#URL of a <Style> or <StyleMap> defined in a Document. #URL of a <Style> or <StyleMap> defined in a Document.
#If the style is in the same file, use a # reference. #If the style is in the same file, use a # reference.
#If the style is defined in an external file, use a full URL #If the style is defined in an external file, use a full URL
...@@ -137,18 +143,37 @@ class _Feature(_BaseObject): ...@@ -137,18 +143,37 @@ class _Feature(_BaseObject):
def __init__(self, ns=None, id=None, name=None, description=None, def __init__(self, ns=None, id=None, name=None, description=None,
styles=None, styleUrl=None): styles=None, styleUrl=None):
self.id = id super(_Feature, self).__init__(ns, id)
self.name=name self.name=name
self.description=description self.description=description
if styleUrl is not None:
self.styleUrl = styleUrl self.styleUrl = styleUrl
self._styles = [] self._styles = []
if styles: if styles:
for style in styles: for style in styles:
self.append_style(style) self.append_style(style)
if ns == None:
self.ns = config.NS @property
def styleUrl(self):
""" Returns the url only, not a full StyleUrl object.
if you need the full StyleUrl use _styleUrl """
if isinstance(self._styleUrl, StyleUrl):
return self._styleUrl.url
@styleUrl.setter
def styleUrl(self, styleurl):
""" you may pass a StyleUrl Object, a string or None """
if isinstance(styleurl, StyleUrl):
self._styleUrl = styleurl
elif isinstance(styleurl, basestring):
s = StyleUrl(self.ns, url=styleurl)
self._styleUrl = s
elif styleurl is None:
self._styleUrl = None
else: else:
self.ns = ns raise ValueError
def append_style(self, style): def append_style(self, style):
""" append a style to the feature """ """ append a style to the feature """
...@@ -167,10 +192,7 @@ class _Feature(_BaseObject): ...@@ -167,10 +192,7 @@ class _Feature(_BaseObject):
def etree_element(self): def etree_element(self):
if self.__name__: element = super(_Feature, self).etree_element()
element = etree.Element(self.ns + self.__name__)
if self.id:
element.set('id', self.id)
if self.name: if self.name:
name = etree.SubElement(element, "%sname" %self.ns) name = etree.SubElement(element, "%sname" %self.ns)
name.text = self.name name.text = self.name
...@@ -181,9 +203,8 @@ class _Feature(_BaseObject): ...@@ -181,9 +203,8 @@ class _Feature(_BaseObject):
visibility.text = str(self.visibility) visibility.text = str(self.visibility)
isopen = etree.SubElement(element, "%sopen" %self.ns) isopen = etree.SubElement(element, "%sopen" %self.ns)
isopen.text = str(self.isopen) isopen.text = str(self.isopen)
if self.styleUrl: if self._styleUrl is not None:
styleUrl = StyleUrl( self.ns, self.styleUrl) element.append(self._styleUrl.etree_element())
element.append(styleUrl.etree_element())
for style in self.styles(): for style in self.styles():
element.append(style.etree_element()) element.append(style.etree_element())
if (self._time_span is not None) and (self._time_stamp is not None): if (self._time_span is not None) and (self._time_stamp is not None):
...@@ -192,8 +213,7 @@ class _Feature(_BaseObject): ...@@ -192,8 +213,7 @@ class _Feature(_BaseObject):
# timespan = TimeStamp(self.ns, begin=self._time_span[0][0], # timespan = TimeStamp(self.ns, begin=self._time_span[0][0],
# begin_res=self._time_span[0][1]) # begin_res=self._time_span[0][1])
else:
raise NotImplementedError
return element return element
...@@ -226,10 +246,11 @@ class _Feature(_BaseObject): ...@@ -226,10 +246,11 @@ class _Feature(_BaseObject):
s.from_element(style) s.from_element(style)
self.append_style(s) self.append_style(s)
style_url = element.find('%sstyleUrl' % self.ns) style_url = element.find('%sstyleUrl' % self.ns)
if style_url: if style_url is not None:
s = StyleUrl(self.ns) s = StyleUrl(self.ns)
s.from_element(style_url) s.from_element(style_url)
self.styleUrl = s.url self._styleUrl = s
#XXX Timespan/stamp
...@@ -248,14 +269,15 @@ class _Container(_Feature): ...@@ -248,14 +269,15 @@ class _Container(_Feature):
def __init__(self, ns=None, id=None, name=None, description=None): def __init__(self, ns=None, id=None, name=None, description=None):
super(_Container, self).__init__(ns, id, name, description) super(_Container, self).__init__(ns, id, name, description)
self._features =[] self._features =[]
if ns == None:
self.ns = config.NS
else:
self.ns = ns
def features(self): def features(self):
""" return a list of features """ """ iterate over features """
return self._features for feature in self._features:
if isinstance(feature, (Folder, Placemark)):
yield feature
else:
raise TypeError(
"Features must be instances of (Folder, Placemark)")
def etree_element(self): def etree_element(self):
element = super(_Container, self).etree_element() element = super(_Container, self).etree_element()
......
...@@ -9,14 +9,10 @@ import logging ...@@ -9,14 +9,10 @@ import logging
logger = logging.getLogger('fastkml.styles') logger = logging.getLogger('fastkml.styles')
import config import config
from config import etree
from base import _BaseObject from base import _BaseObject
try:
from lxml import etree
LXML = True
except ImportError:
import xml.etree.ElementTree as etree
LXML = False
class StyleUrl(_BaseObject): class StyleUrl(_BaseObject):
...@@ -25,34 +21,27 @@ class StyleUrl(_BaseObject): ...@@ -25,34 +21,27 @@ class StyleUrl(_BaseObject):
is in the same file, use a # reference. If the style is defined in is in the same file, use a # reference. If the style is defined in
an external file, use a full URL along with # referencing. an external file, use a full URL along with # referencing.
""" """
__name__ = 'styleUrl'
url = None url = None
def __init__(self, ns=None, url=None): def __init__(self, ns=None, id=None, url=None):
super(StyleUrl, self).__init__(ns, id)
self.url = url self.url = url
if ns == None:
self.ns = config.NS
else:
self.ns = ns
def etree_element(self): def etree_element(self):
if self.url: if self.url:
element = etree.Element(self.ns + "styleUrl") element = super(StyleUrl, self).etree_element()
element.text = self.url element.text = self.url
return element return element
else: else:
logger.critical('No url given for styleUrl') logger.critical('No url given for styleUrl')
raise ValueError raise ValueError
def from_element(self, element): def from_element(self, element):
if self.ns + "styleUrl" != element.tag: super(StyleUrl, self).from_element(element)
raise TypeError
else:
self.url = element.text self.url = element.text
class _StyleSelector(_BaseObject): class _StyleSelector(_BaseObject):
""" """
This is an abstract element and cannot be used directly in a KML file. This is an abstract element and cannot be used directly in a KML file.
...@@ -62,19 +51,6 @@ class _StyleSelector(_BaseObject): ...@@ -62,19 +51,6 @@ class _StyleSelector(_BaseObject):
by its id and its url. by its id and its url.
""" """
def etree_element(self):
element = etree.Element(self.ns + self.__name__)
if self.id:
element.set('id', self.id)
return element
def from_element(self, element):
if self.ns + self.__name__ != element.tag:
raise TypeError
else:
if element.get('id'):
self.id = element.get('id')
class Style(_StyleSelector): class Style(_StyleSelector):
""" """
...@@ -179,7 +155,6 @@ class StyleMap(_StyleSelector): ...@@ -179,7 +155,6 @@ class StyleMap(_StyleSelector):
normal = StyleUrl(self.ns) normal = StyleUrl(self.ns)
normal.from_element(style_url) normal.from_element(style_url)
else: else:
import ipdb; ipdb.set_trace()
raise ValueError raise ValueError
self.normal = normal self.normal = normal
else: else:
...@@ -226,19 +201,13 @@ class _ColorStyle(_BaseObject): ...@@ -226,19 +201,13 @@ class _ColorStyle(_BaseObject):
# A value of random applies a random linear scale to the base <color> # A value of random applies a random linear scale to the base <color>
def __init__(self, ns=None, id=None, color=None, colorMode=None): def __init__(self, ns=None, id=None, color=None, colorMode=None):
self.id = id super(_ColorStyle, self).__init__(ns, id)
if ns == None:
self.ns = config.NS
else:
self.ns = ns
self.color = color self.color = color
self.colorMode = colorMode self.colorMode = colorMode
def etree_element(self): def etree_element(self):
element = etree.Element(self.ns + self.__name__) element = super(_ColorStyle, self).etree_element()
if self.id:
element.set('id', self.id)
if self.color: if self.color:
color = etree.SubElement(element, "%scolor" %self.ns) color = etree.SubElement(element, "%scolor" %self.ns)
color.text = self.color color.text = self.color
......
...@@ -3,6 +3,8 @@ import unittest ...@@ -3,6 +3,8 @@ import unittest
from fastkml import kml from fastkml import kml
from fastkml import styles from fastkml import styles
from fastkml import base
from fastkml import config
import xml.etree.ElementTree as etree import xml.etree.ElementTree as etree
from shapely.geometry import Point, LineString, Polygon from shapely.geometry import Point, LineString, Polygon
from shapely.geometry import MultiPoint, MultiLineString, MultiPolygon from shapely.geometry import MultiPoint, MultiLineString, MultiPolygon
...@@ -13,9 +15,35 @@ class BaseClassesTestCase(unittest.TestCase): ...@@ -13,9 +15,35 @@ class BaseClassesTestCase(unittest.TestCase):
and a TypeError on from_element """ and a TypeError on from_element """
def test_BaseObject(self): def test_BaseObject(self):
pass bo = base._BaseObject(id='id0')
self.assertEqual(bo.id, 'id0')
self.assertEqual(bo.ns, config.NS)
self.assertEqual(bo.targetId, None)
self.assertEqual(bo.__name__, None)
bo.targetId = 'target'
self.assertEqual(bo.targetId, 'target')
bo.ns =''
bo.id =None
self.assertEqual(bo.id, None)
self.assertEqual(bo.ns, '')
self.assertRaises(NotImplementedError, bo.etree_element)
element = etree.Element(config.NS + 'Base')
self.assertRaises(TypeError, bo.from_element)
self.assertRaises(TypeError, bo.from_element, element)
bo.__name__ = 'NotABaseObject'
self.assertRaises(TypeError, bo.from_element, element)
#Note that we can coax baseclasses not to throw errors
bo.__name__ = 'Base'
bo.ns = config.NS
bo.from_element(element)
self.assertEqual(bo.id, None)
self.assertEqual(bo.ns, config.NS)
self.assertFalse(bo.etree_element(), None)
self.assertTrue(len(bo.to_string()) > 1)
def test_Feature(self): def test_Feature(self):
f = kml._Feature(name='A Feature')
f.styleUrl = '#default'
pass pass
def test_Container(self): def test_Container(self):
...@@ -38,7 +66,7 @@ class BuildKmlTestCase(unittest.TestCase): ...@@ -38,7 +66,7 @@ class BuildKmlTestCase(unittest.TestCase):
def test_kml(self): def test_kml(self):
""" kml file without contents """ """ kml file without contents """
k = kml.KML() k = kml.KML()
self.assertEqual(len(k.features()),0) self.assertEqual(len( list(k.features())),0)
self.assertEqual( k.to_string(), self.assertEqual( k.to_string(),
'<ns0:kml xmlns:ns0="http://www.opengis.net/kml/2.2"/>') '<ns0:kml xmlns:ns0="http://www.opengis.net/kml/2.2"/>')
k2 = kml.KML() k2 = kml.KML()
...@@ -56,8 +84,8 @@ class BuildKmlTestCase(unittest.TestCase): ...@@ -56,8 +84,8 @@ class BuildKmlTestCase(unittest.TestCase):
k.append(f) k.append(f)
f2 = kml.Folder(ns, 'id2', 'name2', 'description2') f2 = kml.Folder(ns, 'id2', 'name2', 'description2')
k.append(f2) k.append(f2)
self.assertEqual(len(k.features()),2) self.assertEqual(len(list(k.features())),2)
self.assertEqual(len( k.features()[0].features()),1) self.assertEqual(len( list( list(k.features())[0].features())),1)
k2 = kml.KML() k2 = kml.KML()
s = k.to_string() s = k.to_string()
k2.from_string(s) k2.from_string(s)
...@@ -73,7 +101,7 @@ class BuildKmlTestCase(unittest.TestCase): ...@@ -73,7 +101,7 @@ class BuildKmlTestCase(unittest.TestCase):
p2.geometry = LineString([(0, 0, 0), (1, 1, 1)]) p2.geometry = LineString([(0, 0, 0), (1, 1, 1)])
k.append(p) k.append(p)
k.append(p2) k.append(p2)
self.assertEqual(len(k.features()),2) self.assertEqual(len(list(k.features())),2)
k2 = kml.KML() k2 = kml.KML()
k2.from_string(k.to_string()) k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string()) self.assertEqual(k.to_string(), k2.to_string())
...@@ -96,8 +124,8 @@ class BuildKmlTestCase(unittest.TestCase): ...@@ -96,8 +124,8 @@ class BuildKmlTestCase(unittest.TestCase):
#p2 does not have a geometry! #p2 does not have a geometry!
f2.append(p) f2.append(p)
nf.append(p2) nf.append(p2)
self.assertEqual(len(k.features()),1) self.assertEqual(len(list(k.features())),1)
self.assertEqual(len(k.features()[0].features()),2) self.assertEqual(len(list((list(k.features())[0].features()))),2)
k2 = kml.KML() k2 = kml.KML()
k2.from_string(k.to_string()) k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string()) self.assertEqual(k.to_string(), k2.to_string())
...@@ -136,8 +164,8 @@ class KmlFromStringTestCase( unittest.TestCase ): ...@@ -136,8 +164,8 @@ class KmlFromStringTestCase( unittest.TestCase ):
</kml>""" </kml>"""
k = kml.KML() k = kml.KML()
k.from_string(doc) k.from_string(doc)
self.assertEqual(len(k.features()),1) self.assertEqual(len(list(k.features())),1)
self.assertEqual(len(k.features()[0].features()),2) self.assertEqual(len(list(list(k.features())[0].features())),2)
k2 = kml.KML() k2 = kml.KML()
k2.from_string(k.to_string()) k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string()) self.assertEqual(k.to_string(), k2.to_string())
...@@ -187,8 +215,8 @@ class KmlFromStringTestCase( unittest.TestCase ): ...@@ -187,8 +215,8 @@ class KmlFromStringTestCase( unittest.TestCase ):
</kml>""" </kml>"""
k = kml.KML() k = kml.KML()
k.from_string(doc) k.from_string(doc)
self.assertEqual(len(k.features()),1) self.assertEqual(len(list(k.features())),1)
self.assertEqual(len(k.features()[0].features()),3) self.assertEqual(len(list(list(k.features())[0].features())),3)
k2 = kml.KML() k2 = kml.KML()
k2.from_string(k.to_string()) k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string()) self.assertEqual(k.to_string(), k2.to_string())
...@@ -208,8 +236,8 @@ class KmlFromStringTestCase( unittest.TestCase ): ...@@ -208,8 +236,8 @@ class KmlFromStringTestCase( unittest.TestCase ):
</kml>""" </kml>"""
k = kml.KML() k = kml.KML()
k.from_string(doc) k.from_string(doc)
self.assertEqual(len(k.features()),1) self.assertEqual(len(list(k.features())),1)
self.assertEqual(k.features()[0].name, "Simple placemark") self.assertEqual(list(k.features())[0].name, "Simple placemark")
k2 = kml.KML() k2 = kml.KML()
k2.from_string(k.to_string()) k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string()) self.assertEqual(k.to_string(), k2.to_string())
...@@ -225,9 +253,9 @@ class KmlFromStringTestCase( unittest.TestCase ): ...@@ -225,9 +253,9 @@ class KmlFromStringTestCase( unittest.TestCase ):
</Placemark> </kml>""" </Placemark> </kml>"""
k = kml.KML() k = kml.KML()
k.from_string(doc) k.from_string(doc)
self.assertEqual(len(k.features()),1) self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance( self.assertTrue(isinstance(
k.features()[0].geometry, Polygon)) list(k.features())[0].geometry, Polygon))
k2 = kml.KML() k2 = kml.KML()
k2.from_string(k.to_string()) k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string()) self.assertEqual(k.to_string(), k2.to_string())
...@@ -280,10 +308,10 @@ class KmlFromStringTestCase( unittest.TestCase ): ...@@ -280,10 +308,10 @@ class KmlFromStringTestCase( unittest.TestCase ):
</Placemark></kml>""" </Placemark></kml>"""
k = kml.KML() k = kml.KML()
k.from_string(doc) k.from_string(doc)
self.assertEqual(len(k.features()),1) self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance( self.assertTrue(isinstance(
k.features()[0].geometry, MultiPoint)) list(k.features())[0].geometry, MultiPoint))
self.assertEqual(len(k.features()[0].geometry.geoms), 12) self.assertEqual(len(list(k.features())[0].geometry.geoms), 12)
k2 = kml.KML() k2 = kml.KML()
k2.from_string(k.to_string()) k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string()) self.assertEqual(k.to_string(), k2.to_string())
...@@ -304,10 +332,10 @@ class KmlFromStringTestCase( unittest.TestCase ): ...@@ -304,10 +332,10 @@ class KmlFromStringTestCase( unittest.TestCase ):
</Placemark> </kml>""" </Placemark> </kml>"""
k = kml.KML() k = kml.KML()
k.from_string(doc) k.from_string(doc)
self.assertEqual(len(k.features()),1) self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance( self.assertTrue(isinstance(
k.features()[0].geometry, MultiLineString)) list(k.features())[0].geometry, MultiLineString))
self.assertEqual(len(k.features()[0].geometry.geoms), 4) self.assertEqual(len(list(k.features())[0].geometry.geoms), 4)
k2 = kml.KML() k2 = kml.KML()
k2.from_string(k.to_string()) k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string()) self.assertEqual(k.to_string(), k2.to_string())
...@@ -322,15 +350,52 @@ class KmlFromStringTestCase( unittest.TestCase ): ...@@ -322,15 +350,52 @@ class KmlFromStringTestCase( unittest.TestCase ):
</Placemark> </kml>""" </Placemark> </kml>"""
k = kml.KML() k = kml.KML()
k.from_string(doc) k.from_string(doc)
self.assertEqual(len(k.features()),1) self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance( self.assertTrue(isinstance(
k.features()[0].geometry, MultiPolygon)) list(k.features())[0].geometry, MultiPolygon))
k2 = kml.KML() k2 = kml.KML()
k2.from_string(k.to_string()) k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string()) self.assertEqual(k.to_string(), k2.to_string())
class StyleTestCase( unittest.TestCase ):
def test_styleurl(self):
f = kml.Document()
f.styleUrl = '#somestyle'
self.assertEqual(f.styleUrl, '#somestyle')
self.assertTrue(isinstance(f._styleUrl, styles.StyleUrl))
s = styles.StyleUrl(config.NS, url='#otherstyle')
f.styleUrl = s
self.assertTrue(isinstance(f._styleUrl, styles.StyleUrl))
self.assertEqual(f.styleUrl, '#otherstyle')
class StyleFromStringTestCase( unittest.TestCase ): class StyleFromStringTestCase( unittest.TestCase ):
def test_styleurl(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>
<styleUrl>#default</styleUrl>
</Document>
</kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(list(k.features())),1)
self.assertEqual(list(k.features())[0].styleUrl, '#default')
k2 = kml.KML()
k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string())
def test_balloonstyle(self):
pass
def test_labelstyle(self): def test_labelstyle(self):
doc = """<?xml version="1.0" encoding="UTF-8"?> doc = """<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2"> <kml xmlns="http://www.opengis.net/kml/2.2">
...@@ -346,10 +411,10 @@ class StyleFromStringTestCase( unittest.TestCase ): ...@@ -346,10 +411,10 @@ class StyleFromStringTestCase( unittest.TestCase ):
</kml>""" </kml>"""
k = kml.KML() k = kml.KML()
k.from_string(doc) k.from_string(doc)
self.assertEqual(len(k.features()),1) self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance( self.assertTrue(isinstance(
list(k.features()[0].styles())[0], styles.Style)) list(list(k.features())[0].styles())[0], styles.Style))
style = list(list(k.features()[0].styles())[0].styles())[0] style = list(list(list(k.features())[0].styles())[0].styles())[0]
self.assertTrue(isinstance(style, styles.LabelStyle)) self.assertTrue(isinstance(style, styles.LabelStyle))
self.assertEqual(style.color, 'ff0000cc') self.assertEqual(style.color, 'ff0000cc')
self.assertEqual(style.colorMode, None) self.assertEqual(style.colorMode, None)
...@@ -376,10 +441,10 @@ class StyleFromStringTestCase( unittest.TestCase ): ...@@ -376,10 +441,10 @@ class StyleFromStringTestCase( unittest.TestCase ):
</kml>""" </kml>"""
k = kml.KML() k = kml.KML()
k.from_string(doc) k.from_string(doc)
self.assertEqual(len(k.features()),1) self.assertEqual(len(list((k.features()))),1)
self.assertTrue(isinstance( self.assertTrue(isinstance(
list(k.features()[0].styles())[0], styles.Style)) list(list(k.features())[0].styles())[0], styles.Style))
style = list(list(k.features()[0].styles())[0].styles())[0] style = list(list(list(k.features())[0].styles())[0].styles())[0]
self.assertTrue(isinstance(style, styles.IconStyle)) self.assertTrue(isinstance(style, styles.IconStyle))
self.assertEqual(style.color, 'ff00ff00') self.assertEqual(style.color, 'ff00ff00')
self.assertEqual(style.scale, 1.1) self.assertEqual(style.scale, 1.1)
...@@ -406,10 +471,10 @@ class StyleFromStringTestCase( unittest.TestCase ): ...@@ -406,10 +471,10 @@ class StyleFromStringTestCase( unittest.TestCase ):
</kml>""" </kml>"""
k = kml.KML() k = kml.KML()
k.from_string(doc) k.from_string(doc)
self.assertEqual(len(k.features()),1) self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance( self.assertTrue(isinstance(
list(k.features()[0].styles())[0], styles.Style)) list(list(k.features())[0].styles())[0], styles.Style))
style = list(list(k.features()[0].styles())[0].styles())[0] style = list(list(list(k.features())[0].styles())[0].styles())[0]
self.assertTrue(isinstance(style, styles.LineStyle)) self.assertTrue(isinstance(style, styles.LineStyle))
self.assertEqual(style.color, '7f0000ff') self.assertEqual(style.color, '7f0000ff')
self.assertEqual(style.width, 4) self.assertEqual(style.width, 4)
...@@ -432,13 +497,13 @@ class StyleFromStringTestCase( unittest.TestCase ): ...@@ -432,13 +497,13 @@ class StyleFromStringTestCase( unittest.TestCase ):
</Style> </Style>
</Document> </Document>
</kml>""" </kml>"""
#XXX fil and outline #XXX fill and outline
k = kml.KML() k = kml.KML()
k.from_string(doc) k.from_string(doc)
self.assertEqual(len(k.features()),1) self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance( self.assertTrue(isinstance(
list(k.features()[0].styles())[0], styles.Style)) list(list(k.features())[0].styles())[0], styles.Style))
style = list(list(k.features()[0].styles())[0].styles())[0] style = list(list(list(k.features())[0].styles())[0].styles())[0]
self.assertTrue(isinstance(style, styles.PolyStyle)) self.assertTrue(isinstance(style, styles.PolyStyle))
self.assertEqual(style.color, 'ff0000cc') self.assertEqual(style.color, 'ff0000cc')
self.assertEqual(style.colorMode, 'random') self.assertEqual(style.colorMode, 'random')
...@@ -478,10 +543,10 @@ class StyleFromStringTestCase( unittest.TestCase ): ...@@ -478,10 +543,10 @@ class StyleFromStringTestCase( unittest.TestCase ):
</kml>""" </kml>"""
k = kml.KML() k = kml.KML()
k.from_string(doc) k.from_string(doc)
self.assertEqual(len(k.features()),1) self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance( self.assertTrue(isinstance(
list(k.features()[0].styles())[0], styles.Style)) list(list(k.features())[0].styles())[0], styles.Style))
style = list(list(k.features()[0].styles())[0].styles()) style = list(list(list(k.features())[0].styles())[0].styles())
self.assertEqual(len(style), 4) self.assertEqual(len(style), 4)
k2 = kml.KML() k2 = kml.KML()
k2.from_string(k.to_string()) k2.from_string(k.to_string())
...@@ -506,15 +571,16 @@ class StyleFromStringTestCase( unittest.TestCase ): ...@@ -506,15 +571,16 @@ class StyleFromStringTestCase( unittest.TestCase ):
</kml>""" </kml>"""
k = kml.KML() k = kml.KML()
k.from_string(doc) k.from_string(doc)
self.assertEqual(len(k.features()),1) self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance( self.assertTrue(isinstance(
list(k.features()[0].styles())[0], styles.StyleMap)) list(list(k.features())[0].styles())[0], styles.StyleMap))
sm = list(list(k.features()[0].styles()))[0] sm = list(list(list(k.features())[0].styles()))[0]
self.assertTrue(isinstance(sm.normal, styles.StyleUrl)) self.assertTrue(isinstance(sm.normal, styles.StyleUrl))
self.assertEqual(sm.normal.url, '#normalState') self.assertEqual(sm.normal.url, '#normalState')
self.assertTrue(isinstance(sm.highlight, styles.StyleUrl)) self.assertTrue(isinstance(sm.highlight, styles.StyleUrl))
self.assertEqual(sm.highlight.url, '#highlightState') self.assertEqual(sm.highlight.url, '#highlightState')
k2 = kml.KML() k2 = kml.KML()
ks = k.to_string()
k2.from_string(k.to_string()) k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string()) self.assertEqual(k.to_string(), k2.to_string())
...@@ -549,10 +615,10 @@ class StyleFromStringTestCase( unittest.TestCase ): ...@@ -549,10 +615,10 @@ class StyleFromStringTestCase( unittest.TestCase ):
</kml>""" </kml>"""
k = kml.KML() k = kml.KML()
k.from_string(doc) k.from_string(doc)
self.assertEqual(len(k.features()),1) self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance( self.assertTrue(isinstance(
list(k.features()[0].styles())[0], styles.StyleMap)) list(list(k.features())[0].styles())[0], styles.StyleMap))
sm = list(list(k.features()[0].styles()))[0] sm = list(list(list(k.features())[0].styles()))[0]
self.assertTrue(isinstance(sm.normal, styles.Style)) self.assertTrue(isinstance(sm.normal, styles.Style))
self.assertEqual(len(list(sm.normal.styles())), 1) self.assertEqual(len(list(sm.normal.styles())), 1)
self.assertTrue(isinstance(list(sm.normal.styles())[0], styles.LabelStyle)) self.assertTrue(isinstance(list(sm.normal.styles())[0], styles.LabelStyle))
...@@ -570,6 +636,7 @@ def test_suite(): ...@@ -570,6 +636,7 @@ def test_suite():
suite.addTest(unittest.makeSuite( KmlFromStringTestCase )) suite.addTest(unittest.makeSuite( KmlFromStringTestCase ))
suite.addTest(unittest.makeSuite( BuildKmlTestCase )) suite.addTest(unittest.makeSuite( BuildKmlTestCase ))
suite.addTest(unittest.makeSuite( StyleFromStringTestCase )) suite.addTest(unittest.makeSuite( StyleFromStringTestCase ))
suite.addTest(unittest.makeSuite(BaseClassesTestCase))
return suite return suite
if __name__ == '__main__': if __name__ == '__main__':
......
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