Commit 42f6c6c3 authored by Christian Ledermann's avatar Christian Ledermann

Merge pull request #17 from IanLee1521/master

Add support for GroundOverlay
parents 111e30dd d078a306
......@@ -14,6 +14,7 @@ env:
install:
- pip install -r requirements/test.txt
- if $LXML == true; then pip install lxml; fi
- if [[ $TRAVIS_PYTHON_VERSION == 2.6 ]]; then pip install unittest2; fi
# command to run tests, e.g. python setup.py test
script:
......@@ -26,3 +27,4 @@ after_success:
notifications:
email:
- christian.ledermann@gmail.com
- IanLee1521@gmail.com
......@@ -6,7 +6,8 @@ Changelog
-----------------
- back to development
- Add support for address and phoneNumber
- Add support for address and phoneNumber [Ian Lee]
- Add support for Ground Overlay kml [Ian Lee]
0.7 (2014/08/01)
----------------
......
......@@ -28,7 +28,7 @@ http://schemas.opengis.net/kml/.
try:
import urlparse
except ImportError:
import urllib.parse as urlparse
import urllib.parse as urlparse # Python 3
import warnings
# from .geometry import Point, LineString, Polygon
......@@ -168,12 +168,11 @@ class _Feature(_BaseObject):
"""
abstract element; do not create
subclasses are:
Container (Document, Folder),
Placemark,
#NetworkLink,
#GroundOverlay,
#PhotoOverlay,
#ScreenOverlay
* Container (Document, Folder)
* Placemark
* Overlay
Not Implemented Yet:
* NetworkLink
"""
name = None
# User-defined text displayed in the 3D viewer as the label for the
......@@ -645,6 +644,322 @@ class _Container(_Feature):
assert(kmlobj != self)
class _Overlay(_Feature):
"""
abstract element; do not create
Base type for image overlays drawn on the planet surface or on the screen
A Container element holds one or more Features and allows the creation of
nested hierarchies.
"""
_color = None
# Color values expressed in hexadecimal notation, including opacity (alpha)
# values. The order of expression is alpOverlayha, blue, green, red
# (AABBGGRR). The range of values for any one color is 0 to 255 (00 to ff).
# For opacity, 00 is fully transparent and ff is fully opaque.
_drawOrder = None
# Defines the stacking order for the images in overlapping overlays.
# Overlays with higher <drawOrder> values are drawn on top of those with
# lower <drawOrder> values.
_icon = None
# Defines the image associated with the overlay. Contains an <href> html
# tag which defines the location of the image to be used as the overlay.
# The location can be either on a local file system or on a webserver. If
# this element is omitted or contains no <href>, a rectangle is drawn using
# the color and size defined by the ground or screen overlay.
def __init__(
self, ns=None, id=None, name=None, description=None,
styles=None, styleUrl=None
):
super(_Overlay, self).__init__(
ns, id, name, description, styles, styleUrl
)
@property
def color(self):
return self._color
@color.setter
def color(self, color):
if isinstance(color, basestring):
self._color = color
elif color is None:
self._color = None
else:
raise ValueError
@property
def drawOrder(self):
return self._drawOrder
@drawOrder.setter
def drawOrder(self, value):
if isinstance(value, (basestring, int, float)):
self._drawOrder = str(value)
elif value is None:
self._drawOrder = None
else:
raise ValueError
@property
def icon(self):
return self._icon
@icon.setter
def icon(self, url):
if isinstance(url, basestring):
if not url.startswith('<href>'):
url = '<href>' + url
if not url.endswith('</href>'):
url = url + '</href>'
self._icon = url
elif url is None:
self._icon = None
else:
raise ValueError
def etree_element(self):
element = super(_Overlay, self).etree_element()
if self._color:
color = etree.SubElement(element, "%scolor" % self.ns)
color.text = self._color
if self._drawOrder:
drawOrder = etree.SubElement(element, "%sdrawOrder" % self.ns)
drawOrder.text = self._drawOrder
if self._icon:
icon = etree.SubElement(element, "%sicon" % self.ns)
icon.text = self._icon
return element
def from_element(self, element):
super(_Overlay, self).from_element(element)
color = element.find('%scolor' % self.ns)
if color is not None:
self.color = color.text
drawOrder = element.find('%sdrawOrder' % self.ns)
if drawOrder is not None:
self.drawOrder = drawOrder.text
icon = element.find('%sicon' % self.ns)
if icon is not None:
self.icon = icon.text
class GroundOverlay(_Overlay):
"""
This element draws an image overlay draped onto the terrain. The <href>
child of <Icon> specifies the image to be used as the overlay. This file
can be either on a local file system or on a web server. If this element is
omitted or contains no <href>, a rectangle is drawn using the color and
LatLonBox bounds defined by the ground overlay.
"""
__name__ = 'GroundOverlay'
_altitude = None
# Specifies the distance above the earth's surface, in meters, and is
# interpreted according to the altitude mode.
_altitudeMode = 'clampToGround'
# Specifies how the <altitude> is interpreted. Possible values are:
# clampToGround -
# (default) Indicates to ignore the altitude specification and drape
# the overlay over the terrain.
# absolute -
# Sets the altitude of the overlay relative to sea level, regardless
# of the actual elevation of the terrain beneath the element. For
# example, if you set the altitude of an overlay to 10 meters with an
# absolute altitude mode, the overlay will appear to be at ground
# level if the terrain beneath is also 10 meters above sea level. If
# the terrain is 3 meters above sea level, the overlay will appear
# elevated above the terrain by 7 meters.
# - LatLonBox -
# TODO: Convert this to it's own class?
# Specifies where the top, bottom, right, and left sides of a bounding box
# for the ground overlay are aligned. Also, optionally the rotation of the
# overlay.
_north = None
# Specifies the latitude of the north edge of the bounding box, in decimal
# degrees from 0 to ±90.
_south = None
# Specifies the latitude of the south edge of the bounding box, in decimal
# degrees from 0 to ±90.
_east = None
# Specifies the longitude of the east edge of the bounding box, in decimal
# degrees from 0 to ±180. (For overlays that overlap the meridian of 180°
# longitude, values can extend beyond that range.)
_west = None
# Specifies the longitude of the west edge of the bounding box, in decimal
# degrees from 0 to ±180. (For overlays that overlap the meridian of 180°
# longitude, values can extend beyond that range.)
_rotation = None
# Specifies a rotation of the overlay about its center, in degrees. Values
# can be ±180. The default is 0 (north). Rotations are specified in a
# counterclockwise direction.
# TODO: <gx:LatLonQuad>
# Used for nonrectangular quadrilateral ground overlays.
_latLonQuad = None
@property
def altitude(self):
return self._altitude
@altitude.setter
def altitude(self, value):
if isinstance(value, (basestring, int, float)):
self._altitude = str(value)
elif value is None:
self._altitude = None
else:
raise ValueError
@property
def altitudeMode(self):
return self._altitudeMode
@altitudeMode.setter
def altitudeMode(self, mode):
if mode in ('clampToGround', 'absolute'):
self._altitudeMode = str(mode)
else:
self._altitudeMode = 'clampToGround'
@property
def north(self):
return self._north
@north.setter
def north(self, value):
if isinstance(value, (basestring, int, float)):
self._north = str(value)
elif value is None:
self._north = None
else:
raise ValueError
@property
def south(self):
return self._south
@south.setter
def south(self, value):
if isinstance(value, (basestring, int, float)):
self._south = str(value)
elif value is None:
self._south = None
else:
raise ValueError
@property
def east(self):
return self._east
@east.setter
def east(self, value):
if isinstance(value, (basestring, int, float)):
self._east = str(value)
elif value is None:
self._east = None
else:
raise ValueError
@property
def west(self):
return self._west
@west.setter
def west(self, value):
if isinstance(value, (basestring, int, float)):
self._west = str(value)
elif value is None:
self._west = None
else:
raise ValueError
@property
def rotation(self):
return self._rotation
@rotation.setter
def rotation(self, value):
if isinstance(value, (basestring, int, float)):
self._rotation = str(value)
elif value is None:
self._rotation = None
else:
raise ValueError
def latLonBox(self, north, south, east, west, rotation=0):
# TODO: Check for bounds (0:+/-90 or 0:+/-180 degrees)
self.north = north
self.south = south
self.east = east
self.west = west
self.rotation = rotation
def etree_element(self):
element = super(GroundOverlay, self).etree_element()
if self._altitude:
altitude = etree.SubElement(element, "%saltitude" % self.ns)
altitude.text = self._altitude
if self._altitudeMode:
altitudeMode = etree.SubElement(
element, "%saltitudeMode" % self.ns
)
altitudeMode.text = self._altitudeMode
if all([self._north, self._south, self._east, self._west]):
latLonBox = etree.SubElement(element, '%slatLonBox' % self.ns)
north = etree.SubElement(latLonBox, '%snorth' % self.ns)
north.text = self._north
south = etree.SubElement(latLonBox, '%ssouth' % self.ns)
south.text = self._south
east = etree.SubElement(latLonBox, '%seast' % self.ns)
east.text = self._east
west = etree.SubElement(latLonBox, '%swest' % self.ns)
west.text = self._west
if self._rotation:
rotation = etree.SubElement(latLonBox, '%srotation' % self.ns)
rotation.text = self._rotation
return element
def from_element(self, element):
super(GroundOverlay, self).from_element(element)
altitude = element.find('%saltitude' % self.ns)
if altitude is not None:
self.altitude = altitude.text
altitudeMode = element.find('%saltitudeMode' % self.ns)
if altitudeMode is not None:
self.altitudeMode = altitudeMode.text
latLonBox = element.find('%slatLonBox' % self.ns)
if latLonBox is not None:
north = latLonBox.find('%snorth' % self.ns)
if north is not None:
self.north = north.text
south = latLonBox.find('%ssouth' % self.ns)
if south is not None:
self.south = south.text
east = latLonBox.find('%seast' % self.ns)
if east is not None:
self.east = east.text
west = latLonBox.find('%swest' % self.ns)
if west is not None:
self.west = west.text
rotation = latLonBox.find('%srotation' % self.ns)
if rotation is not None:
self.rotation = rotation.text
class Document(_Container):
"""
A Document is a container for features and styles. This element is
......
......@@ -15,13 +15,17 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import unittest
try:
import unittest2 as unittest # Needed in Python 2.6
except:
import unittest
from fastkml import kml
from fastkml import styles
from fastkml import base
from fastkml import atom
from fastkml import config
from fastkml import gx # NOQA
import datetime
from dateutil.tz import tzutc, tzoffset
......@@ -92,8 +96,8 @@ class BaseClassesTestCase(unittest.TestCase):
def test_Container(self):
f = kml._Container(name='A Container')
# apparently you can add documents to containes
#d = kml.Document()
#self.assertRaises(TypeError, f.append, d)
# d = kml.Document()
# self.assertRaises(TypeError, f.append, d)
p = kml.Placemark()
f.append(p)
self.assertRaises(NotImplementedError, f.etree_element)
......@@ -110,6 +114,23 @@ class BaseClassesTestCase(unittest.TestCase):
def test_Person(self):
pass
def test_Overlay(self):
o = kml._Overlay(name='An Overlay')
self.assertEqual(o._color, None)
self.assertEqual(o._drawOrder, None)
self.assertEqual(o._icon, None)
self.assertRaises(NotImplementedError, o.etree_element)
def test_atom_link(self):
ns = '{http://www.opengis.net/kml/2.2}'
l = atom.Link(ns=ns)
self.assertEqual(l.ns, ns)
def test_atom_person(self):
ns = '{http://www.opengis.net/kml/2.2}'
p = atom._Person(ns=ns)
self.assertEqual(p.ns, ns)
class BuildKmlTestCase(unittest.TestCase):
""" Build a simple KML File """
......@@ -833,7 +854,7 @@ class KmlFromStringTestCase(unittest.TestCase):
<kml:name>pm-name</kml:name>
<kml:description>pm-description</kml:description>
<kml:visibility>1</kml:visibility>
<kml:address>3901 Holly Dr, San Jose, CA 95060</kml:address>
<kml:address>1600 Amphitheatre Parkway, Mountain View, CA 94043, USA</kml:address>
</kml:Document>
""")
......@@ -857,6 +878,39 @@ class KmlFromStringTestCase(unittest.TestCase):
doc2.from_string(doc.to_string())
self.assertEqual(doc.to_string(), doc2.to_string())
def test_groundoverlay(self):
doc = kml.KML()
doc.from_string(
"""
<kml xmlns="http://www.opengis.net/kml/2.2">
<Folder>
<name>Ground Overlays</name>
<description>Examples of ground overlays</description>
<GroundOverlay>
<name>Large-scale overlay on terrain</name>
<description>Overlay shows Mount Etna erupting
on July 13th, 2001.</description>
<Icon>
<href>http://developers.google.com/kml/documentation/images/etna.jpg</href>
</Icon>
<LatLonBox>
<north>37.91904192681665</north>
<south>37.46543388598137</south>
<east>15.35832653742206</east>
<west>14.60128369746704</west>
<rotation>-0.1556640799496235</rotation>
</LatLonBox>
</GroundOverlay>
</Folder>
</kml>
"""
)
doc2 = kml.KML()
doc2.from_string(doc.to_string())
self.assertEqual(doc.to_string(), doc2.to_string())
class StyleTestCase(unittest.TestCase):
def test_styleurl(self):
......@@ -1932,6 +1986,438 @@ class Force3DTestCase(unittest.TestCase):
config.FORCE3D = False
class BaseFeatureTestCase(unittest.TestCase):
def test_address_string(self):
f = kml._Feature()
address = '1600 Amphitheatre Parkway, Mountain View, CA 94043, USA'
f.address = address
self.assertEqual(f.address, address)
def test_address_none(self):
f = kml._Feature()
f.address = None
self.assertEqual(f.address, None)
def test_address_value_error(self):
f = kml._Feature()
with self.assertRaises(ValueError):
f.address = 123
def test_phone_number_string(self):
f = kml._Feature()
f.phoneNumber = '+1-234-567-8901'
self.assertEqual(f.phoneNumber, '+1-234-567-8901')
def test_phone_number_none(self):
f = kml._Feature()
f.phoneNumber = None
self.assertEqual(f.phoneNumber, None)
def test_phone_number_value_error(self):
f = kml._Feature()
with self.assertRaises(ValueError):
f.phoneNumber = 123
class BaseOverlayTestCase(unittest.TestCase):
def test_color_string(self):
o = kml._Overlay(name='An Overlay')
o.color = '00010203'
self.assertEqual(o.color, '00010203')
def test_color_none(self):
o = kml._Overlay(name='An Overlay')
o.color = '00010203'
self.assertEqual(o.color, '00010203')
o.color = None
self.assertEqual(o.color, None)
def test_color_value_error(self):
o = kml._Overlay(name='An Overlay')
with self.assertRaises(ValueError):
o.color = object()
def test_draw_order_string(self):
o = kml._Overlay(name='An Overlay')
o.drawOrder = '1'
self.assertEqual(o.drawOrder, '1')
def test_draw_order_int(self):
o = kml._Overlay(name='An Overlay')
o.drawOrder = 1
self.assertEqual(o.drawOrder, '1')
def test_draw_order_none(self):
o = kml._Overlay(name='An Overlay')
o.drawOrder = '1'
self.assertEqual(o.drawOrder, '1')
o.drawOrder = None
self.assertEqual(o.drawOrder, None)
def test_draw_order_value_error(self):
o = kml._Overlay(name='An Overlay')
with self.assertRaises(ValueError):
o.drawOrder = object()
def test_icon_without_tag(self):
o = kml._Overlay(name='An Overlay')
o.icon = 'http://example.com/'
self.assertEqual(o.icon, '<href>http://example.com/</href>')
def test_icon_with_open_tag(self):
o = kml._Overlay(name='An Overlay')
o.icon = '<href>http://example.com/'
self.assertEqual(o.icon, '<href>http://example.com/</href>')
def test_icon_with_close_tag(self):
o = kml._Overlay(name='An Overlay')
o.icon = 'http://example.com/</href>'
self.assertEqual(o.icon, '<href>http://example.com/</href>')
def test_icon_with_tag(self):
o = kml._Overlay(name='An Overlay')
o.icon = '<href>http://example.com/</href>'
self.assertEqual(o.icon, '<href>http://example.com/</href>')
def test_icon_to_none(self):
o = kml._Overlay(name='An Overlay')
o.icon = '<href>http://example.com/</href>'
self.assertEqual(o.icon, '<href>http://example.com/</href>')
o.icon = None
self.assertEqual(o.icon, None)
def test_icon_raise_exception(self):
o = kml._Overlay(name='An Overlay')
with self.assertRaises(ValueError):
o.icon = 12345
class GroundOverlayTestCase(unittest.TestCase):
def setUp(self):
self.g = kml.GroundOverlay()
def test_altitude_int(self):
self.g.altitude = 123
self.assertEqual(self.g.altitude, '123')
def test_altitude_float(self):
self.g.altitude = 123.4
self.assertEqual(self.g.altitude, '123.4')
def test_altitude_string(self):
self.g.altitude = '123'
self.assertEqual(self.g.altitude, '123')
def test_altitude_value_error(self):
with self.assertRaises(ValueError):
self.g.altitude = object()
def test_altitude_none(self):
self.g.altitude = '123'
self.assertEqual(self.g.altitude, '123')
self.g.altitude = None
self.assertEqual(self.g.altitude, None)
def test_altitude_mode_default(self):
self.assertEqual(self.g.altitudeMode, 'clampToGround')
def test_altitude_mode_error(self):
self.g.altitudeMode = ''
self.assertEqual(self.g.altitudeMode, 'clampToGround')
def test_altitude_mode_clamp(self):
self.g.altitudeMode = 'clampToGround'
self.assertEqual(self.g.altitudeMode, 'clampToGround')
def test_altitude_mode_absolute(self):
self.g.altitudeMode = 'absolute'
self.assertEqual(self.g.altitudeMode, 'absolute')
def test_latlonbox_function(self):
self.g.latLonBox(10, 20, 30, 40, 50)
self.assertEqual(self.g.north, '10')
self.assertEqual(self.g.south, '20')
self.assertEqual(self.g.east, '30')
self.assertEqual(self.g.west, '40')
self.assertEqual(self.g.rotation, '50')
def test_latlonbox_string(self):
self.g.north = '10'
self.g.south = '20'
self.g.east = '30'
self.g.west = '40'
self.g.rotation = '50'
self.assertEqual(self.g.north, '10')
self.assertEqual(self.g.south, '20')
self.assertEqual(self.g.east, '30')
self.assertEqual(self.g.west, '40')
self.assertEqual(self.g.rotation, '50')
def test_latlonbox_int(self):
self.g.north = 10
self.g.south = 20
self.g.east = 30
self.g.west = 40
self.g.rotation = 50
self.assertEqual(self.g.north, '10')
self.assertEqual(self.g.south, '20')
self.assertEqual(self.g.east, '30')
self.assertEqual(self.g.west, '40')
self.assertEqual(self.g.rotation, '50')
def test_latlonbox_float(self):
self.g.north = 10.0
self.g.south = 20.0
self.g.east = 30.0
self.g.west = 40.0
self.g.rotation = 50.0
self.assertEqual(self.g.north, '10.0')
self.assertEqual(self.g.south, '20.0')
self.assertEqual(self.g.east, '30.0')
self.assertEqual(self.g.west, '40.0')
self.assertEqual(self.g.rotation, '50.0')
def test_latlonbox_value_error(self):
with self.assertRaises(ValueError):
self.g.north = object()
with self.assertRaises(ValueError):
self.g.south = object()
with self.assertRaises(ValueError):
self.g.east = object()
with self.assertRaises(ValueError):
self.g.west = object()
with self.assertRaises(ValueError):
self.g.rotation = object()
self.assertEqual(self.g.north, None)
self.assertEqual(self.g.south, None)
self.assertEqual(self.g.east, None)
self.assertEqual(self.g.west, None)
self.assertEqual(self.g.rotation, None)
def test_latlonbox_empty_string(self):
self.g.north = ''
self.g.south = ''
self.g.east = ''
self.g.west = ''
self.g.rotation = ''
self.assertEqual(self.g.north, '')
self.assertEqual(self.g.south, '')
self.assertEqual(self.g.east, '')
self.assertEqual(self.g.west, '')
self.assertEqual(self.g.rotation, '')
def test_latlonbox_none(self):
self.g.north = None
self.g.south = None
self.g.east = None
self.g.west = None
self.g.rotation = None
self.assertEqual(self.g.north, None)
self.assertEqual(self.g.south, None)
self.assertEqual(self.g.east, None)
self.assertEqual(self.g.west, None)
self.assertEqual(self.g.rotation, None)
class GroundOverlayStringTestCase(unittest.TestCase):
def test_default_to_string(self):
g = kml.GroundOverlay()
expected = kml.GroundOverlay()
expected.from_string(
'<kml:GroundOverlay xmlns:kml="http://www.opengis.net/kml/2.2">'
'<kml:visibility>1</kml:visibility>'
'</kml:GroundOverlay>'
)
self.assertEqual(g.to_string(), expected.to_string())
def test_to_string(self):
g = kml.GroundOverlay()
g.icon = 'http://example.com'
g.drawOrder = 1
g.color = '00010203'
expected = kml.GroundOverlay()
expected.from_string(
'<kml:GroundOverlay xmlns:kml="http://www.opengis.net/kml/2.2">'
'<kml:visibility>1</kml:visibility>'
'<kml:color>00010203</kml:color>'
'<kml:drawOrder>1</kml:drawOrder>'
'<kml:icon>&lt;href&gt;http://example.com&lt;/href&gt;</kml:icon>'
'</kml:GroundOverlay>'
)
self.assertEqual(g.to_string(), expected.to_string())
def test_altitude_from_int(self):
g = kml.GroundOverlay()
g.altitude = 123
expected = kml.GroundOverlay()
expected.from_string(
'<kml:GroundOverlay xmlns:kml="http://www.opengis.net/kml/2.2">'
'<kml:visibility>1</kml:visibility>'
'<kml:altitude>123</kml:altitude>'
'<kml:altitudeMode>clampToGround</kml:altitudeMode>'
'</kml:GroundOverlay>'
)
self.assertEqual(g.to_string(), expected.to_string())
def test_altitude_from_float(self):
g = kml.GroundOverlay()
g.altitude = 123.4
expected = kml.GroundOverlay()
expected.from_string(
'<kml:GroundOverlay xmlns:kml="http://www.opengis.net/kml/2.2">'
'<kml:visibility>1</kml:visibility>'
'<kml:altitude>123.4</kml:altitude>'
'<kml:altitudeMode>clampToGround</kml:altitudeMode>'
'</kml:GroundOverlay>'
)
self.assertEqual(g.to_string(), expected.to_string())
def test_altitude_from_string(self):
g = kml.GroundOverlay()
g.altitude = '123.4'
expected = kml.GroundOverlay()
expected.from_string(
'<kml:GroundOverlay xmlns:kml="http://www.opengis.net/kml/2.2">'
'<kml:visibility>1</kml:visibility>'
'<kml:altitude>123.4</kml:altitude>'
'<kml:altitudeMode>clampToGround</kml:altitudeMode>'
'</kml:GroundOverlay>'
)
self.assertEqual(g.to_string(), expected.to_string())
def test_altitude_mode_absolute(self):
g = kml.GroundOverlay()
g.altitude = '123.4'
g.altitudeMode = 'absolute'
expected = kml.GroundOverlay()
expected.from_string(
'<kml:GroundOverlay xmlns:kml="http://www.opengis.net/kml/2.2">'
'<kml:visibility>1</kml:visibility>'
'<kml:altitude>123.4</kml:altitude>'
'<kml:altitudeMode>absolute</kml:altitudeMode>'
'</kml:GroundOverlay>'
)
self.assertEqual(g.to_string(), expected.to_string())
def test_altitude_mode_unknown_string(self):
g = kml.GroundOverlay()
g.altitude = '123.4'
g.altitudeMode = 'unknown string'
expected = kml.GroundOverlay()
expected.from_string(
'<kml:GroundOverlay xmlns:kml="http://www.opengis.net/kml/2.2">'
'<kml:visibility>1</kml:visibility>'
'<kml:altitude>123.4</kml:altitude>'
'<kml:altitudeMode>clampToGround</kml:altitudeMode>'
'</kml:GroundOverlay>'
)
self.assertEqual(g.to_string(), expected.to_string())
def test_altitude_mode_value(self):
g = kml.GroundOverlay()
g.altitude = '123.4'
g.altitudeMode = 1234
expected = kml.GroundOverlay()
expected.from_string(
'<kml:GroundOverlay xmlns:kml="http://www.opengis.net/kml/2.2">'
'<kml:visibility>1</kml:visibility>'
'<kml:altitude>123.4</kml:altitude>'
'<kml:altitudeMode>clampToGround</kml:altitudeMode>'
'</kml:GroundOverlay>'
)
self.assertEqual(g.to_string(), expected.to_string())
def test_latlonbox_no_rotation(self):
g = kml.GroundOverlay()
g.latLonBox(10, 20, 30, 40)
expected = kml.GroundOverlay()
expected.from_string(
'<kml:GroundOverlay xmlns:kml="http://www.opengis.net/kml/2.2">'
'<kml:visibility>1</kml:visibility>'
'<kml:latLonBox>'
'<kml:north>10</kml:north>'
'<kml:south>20</kml:south>'
'<kml:east>30</kml:east>'
'<kml:west>40</kml:west>'
'<kml:rotation>0</kml:rotation>'
'</kml:latLonBox>'
'</kml:GroundOverlay>'
)
self.assertEqual(g.to_string(), expected.to_string())
def test_latlonbox_rotation(self):
g = kml.GroundOverlay()
g.latLonBox(10, 20, 30, 40, 50)
expected = kml.GroundOverlay()
expected.from_string(
'<kml:GroundOverlay xmlns:kml="http://www.opengis.net/kml/2.2">'
'<kml:visibility>1</kml:visibility>'
'<kml:latLonBox>'
'<kml:north>10</kml:north>'
'<kml:south>20</kml:south>'
'<kml:east>30</kml:east>'
'<kml:west>40</kml:west>'
'<kml:rotation>50</kml:rotation>'
'</kml:latLonBox>'
'</kml:GroundOverlay>'
)
self.assertEqual(g.to_string(), expected.to_string())
def test_latlonbox_nswer(self):
g = kml.GroundOverlay()
g.north = 10
g.south = 20
g.east = 30
g.west = 40
g.rotation = 50
expected = kml.GroundOverlay()
expected.from_string(
'<kml:GroundOverlay xmlns:kml="http://www.opengis.net/kml/2.2">'
'<kml:visibility>1</kml:visibility>'
'<kml:latLonBox>'
'<kml:north>10</kml:north>'
'<kml:south>20</kml:south>'
'<kml:east>30</kml:east>'
'<kml:west>40</kml:west>'
'<kml:rotation>50</kml:rotation>'
'</kml:latLonBox>'
'</kml:GroundOverlay>'
)
self.assertEqual(g.to_string(), expected.to_string())
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(BaseClassesTestCase))
......@@ -1944,6 +2430,8 @@ def test_suite():
suite.addTest(unittest.makeSuite(SetGeometryTestCase))
suite.addTest(unittest.makeSuite(GetGeometryTestCase))
suite.addTest(unittest.makeSuite(Force3DTestCase))
suite.addTest(unittest.makeSuite(BaseOverlayTestCase))
suite.addTest(unittest.makeSuite(GroundOverlayTestCase))
return suite
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