[owslib] 01/03: Imported Upstream version 0.8.12
Johan Van de Wauw
johanvdw-guest at moszumanska.debian.org
Tue Dec 23 21:28:04 UTC 2014
This is an automated email from the git hooks/post-receive script.
johanvdw-guest pushed a commit to branch master
in repository owslib.
commit 58865a94d623537109b1d21e42529bee68e40a6d
Author: Johan Van de Wauw <johan.vandewauw at gmail.com>
Date: Tue Dec 23 22:09:23 2014 +0100
Imported Upstream version 0.8.12
---
OWSLib.egg-info/PKG-INFO | 2 +-
OWSLib.egg-info/requires.txt | 2 +-
PKG-INFO | 2 +-
VERSION.txt | 2 +-
owslib/__init__.py | 2 +-
owslib/feature/__init__.py | 8 +-
owslib/feature/wfs100.py | 20 ++-
owslib/feature/wfs110.py | 21 ++-
owslib/feature/wfs200.py | 29 ++--
owslib/fes.py | 28 +++-
owslib/swe/observation/sos100.py | 27 ++--
owslib/swe/observation/sos200.py | 31 ++--
owslib/util.py | 29 +++-
owslib/wfs.py | 13 +-
owslib/wms.py | 5 +-
owslib/wmts.py | 333 +++++++++++++++++++++++++--------------
owslib/wps.py | 5 +-
requirements-dev.txt | 1 +
18 files changed, 356 insertions(+), 204 deletions(-)
diff --git a/OWSLib.egg-info/PKG-INFO b/OWSLib.egg-info/PKG-INFO
index 9227ad9..c16916a 100644
--- a/OWSLib.egg-info/PKG-INFO
+++ b/OWSLib.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: OWSLib
-Version: 0.8.10
+Version: 0.8.12
Summary: OGC Web Service utility library
Home-page: http://geopython.github.io/OWSLib
Author: Tom Kralidis
diff --git a/OWSLib.egg-info/requires.txt b/OWSLib.egg-info/requires.txt
index 306406a..8b6b3b8 100644
--- a/OWSLib.egg-info/requires.txt
+++ b/OWSLib.egg-info/requires.txt
@@ -1,2 +1,2 @@
python-dateutil>=1.5
-pytz
\ No newline at end of file
+pytz
diff --git a/PKG-INFO b/PKG-INFO
index 9227ad9..c16916a 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: OWSLib
-Version: 0.8.10
+Version: 0.8.12
Summary: OGC Web Service utility library
Home-page: http://geopython.github.io/OWSLib
Author: Tom Kralidis
diff --git a/VERSION.txt b/VERSION.txt
index ef50561..7eff8ab 100644
--- a/VERSION.txt
+++ b/VERSION.txt
@@ -1 +1 @@
-0.8.10
+0.8.12
diff --git a/owslib/__init__.py b/owslib/__init__.py
index c2c9176..0a5ca3c 100644
--- a/owslib/__init__.py
+++ b/owslib/__init__.py
@@ -1 +1 @@
-__version__ = '0.8.10'
+__version__ = '0.8.12'
diff --git a/owslib/feature/__init__.py b/owslib/feature/__init__.py
index 5a9b224..91030d1 100644
--- a/owslib/feature/__init__.py
+++ b/owslib/feature/__init__.py
@@ -11,7 +11,7 @@ from urllib import urlencode
import logging
from owslib.util import log
-class WebFeatureService_:
+class WebFeatureService_(object):
"""Base class for WebFeatureService implementations"""
def getBBOXKVP (self,bbox,typename):
@@ -76,7 +76,7 @@ class WebFeatureService_:
def getGETGetFeatureRequest(self, typename=None, filter=None, bbox=None, featureid=None,
featureversion=None, propertyname=None, maxfeatures=None,storedQueryID=None, storedQueryParams={},
- outputFormat=None, method='Get'):
+ outputFormat=None, method='Get', startindex=None):
"""Formulate proper GetFeature request using KVP encoding
----------
typename : list
@@ -97,6 +97,8 @@ class WebFeatureService_:
Qualified name of the HTTP DCP method to use.
outputFormat: string (optional)
Requested response format of the request.
+ startindex: int (optional)
+ Start position to return feature set (paging in combination with maxfeatures)
There are 3 different modes of use
@@ -126,6 +128,8 @@ class WebFeatureService_:
request['featureversion'] = str(featureversion)
if maxfeatures:
request['maxfeatures'] = str(maxfeatures)
+ if startindex:
+ request['startindex'] = str(startindex)
if storedQueryID:
request['storedQuery_id']=str(storedQueryID)
for param in storedQueryParams:
diff --git a/owslib/feature/wfs100.py b/owslib/feature/wfs100.py
index 9fb25e5..13975f7 100644
--- a/owslib/feature/wfs100.py
+++ b/owslib/feature/wfs100.py
@@ -49,7 +49,7 @@ class WebFeatureService_1_0_0(object):
Implements IWebFeatureService.
"""
- def __new__(self,url, version, xml, parse_remote_metadata=False):
+ def __new__(self,url, version, xml, parse_remote_metadata=False, timeout=30):
""" overridden __new__ method
@type url: string
@@ -58,10 +58,11 @@ class WebFeatureService_1_0_0(object):
@param xml: elementtree object
@type parse_remote_metadata: boolean
@param parse_remote_metadata: whether to fully process MetadataURL elements
+ @param timeout: time (in seconds) after which requests should timeout
@return: initialized WebFeatureService_1_0_0 object
"""
obj=object.__new__(self)
- obj.__init__(url, version, xml, parse_remote_metadata)
+ obj.__init__(url, version, xml, parse_remote_metadata, timeout)
return obj
def __getitem__(self,name):
@@ -72,10 +73,11 @@ class WebFeatureService_1_0_0(object):
raise KeyError, "No content named %s" % name
- def __init__(self, url, version, xml=None, parse_remote_metadata=False):
+ def __init__(self, url, version, xml=None, parse_remote_metadata=False, timeout=30):
"""Initialize."""
self.url = url
self.version = version
+ self.timeout = timeout
self._capabilities = None
reader = WFSCapabilitiesReader(self.version)
if xml:
@@ -113,12 +115,12 @@ class WebFeatureService_1_0_0(object):
self.exceptions = [f.text for f \
in self._capabilities.findall('Capability/Exception/Format')]
- def getcapabilities(self, timeout=30):
+ def getcapabilities(self):
"""Request and return capabilities document from the WFS as a
file-like object.
NOTE: this is effectively redundant now"""
reader = WFSCapabilitiesReader(self.version)
- return urlopen(reader.capabilities_url(self.url), timeout=timeout)
+ return urlopen(reader.capabilities_url(self.url), timeout=self.timeout)
def items(self):
'''supports dict-like items() access'''
@@ -129,7 +131,8 @@ class WebFeatureService_1_0_0(object):
def getfeature(self, typename=None, filter=None, bbox=None, featureid=None,
featureversion=None, propertyname=['*'], maxfeatures=None,
- srsname=None, outputFormat=None, method='{http://www.opengis.net/wfs}Get'):
+ srsname=None, outputFormat=None, method='{http://www.opengis.net/wfs}Get',
+ startindex=None):
"""Request and return feature data as a file-like object.
Parameters
@@ -154,6 +157,8 @@ class WebFeatureService_1_0_0(object):
EPSG code to request the data in
outputFormat: string (optional)
Requested response format of the request.
+ startindex: int (optional)
+ Start position to return feature set (paging in combination with maxfeatures)
There are 3 different modes of use
@@ -186,13 +191,14 @@ class WebFeatureService_1_0_0(object):
request['propertyname'] = ','.join(propertyname)
if featureversion: request['featureversion'] = str(featureversion)
if maxfeatures: request['maxfeatures'] = str(maxfeatures)
+ if startindex: request['startindex'] = str(startindex)
if outputFormat is not None:
request["outputFormat"] = outputFormat
data = urlencode(request)
log.debug("Making request: %s?%s" % (base_url, data))
- u = openURL(base_url, data, method)
+ u = openURL(base_url, data, method, timeout=self.timeout)
# check for service exceptions, rewrap, and return
diff --git a/owslib/feature/wfs110.py b/owslib/feature/wfs110.py
index 590a8da..8f30c03 100644
--- a/owslib/feature/wfs110.py
+++ b/owslib/feature/wfs110.py
@@ -32,7 +32,7 @@ class WebFeatureService_1_1_0(WebFeatureService_):
Implements IWebFeatureService.
"""
- def __new__(self,url, version, xml, parse_remote_metadata=False):
+ def __new__(self,url, version, xml, parse_remote_metadata=False, timeout=30):
""" overridden __new__ method
@type url: string
@@ -41,10 +41,11 @@ class WebFeatureService_1_1_0(WebFeatureService_):
@param xml: elementtree object
@type parse_remote_metadata: boolean
@param parse_remote_metadata: whether to fully process MetadataURL elements
+ @param timeout: time (in seconds) after which requests should timeout
@return: initialized WebFeatureService_1_1_0 object
"""
obj=object.__new__(self)
- obj.__init__(url, version, xml, parse_remote_metadata)
+ obj.__init__(url, version, xml, parse_remote_metadata, timeout)
return obj
def __getitem__(self,name):
@@ -55,10 +56,11 @@ class WebFeatureService_1_1_0(WebFeatureService_):
raise KeyError, "No content named %s" % name
- def __init__(self, url, version, xml=None, parse_remote_metadata=False):
+ def __init__(self, url, version, xml=None, parse_remote_metadata=False, timeout=30):
"""Initialize."""
self.url = url
self.version = version
+ self.timeout = timeout
self._capabilities = None
self.owscommon = OwsCommon('1.0.0')
reader = WFSCapabilitiesReader(self.version)
@@ -99,12 +101,12 @@ class WebFeatureService_1_1_0(WebFeatureService_):
self.exceptions = [f.text for f \
in self._capabilities.findall('Capability/Exception/Format')]
- def getcapabilities(self, timeout=30):
+ def getcapabilities(self):
"""Request and return capabilities document from the WFS as a
file-like object.
NOTE: this is effectively redundant now"""
reader = WFSCapabilitiesReader(self.version)
- return urlopen(reader.capabilities_url(self.url), timeout=timeout)
+ return urlopen(reader.capabilities_url(self.url), timeout=self.timeout)
def items(self):
'''supports dict-like items() access'''
@@ -115,7 +117,8 @@ class WebFeatureService_1_1_0(WebFeatureService_):
def getfeature(self, typename=None, filter=None, bbox=None, featureid=None,
featureversion=None, propertyname=['*'], maxfeatures=None,
- srsname=None, outputFormat=None, method='Get'):
+ srsname=None, outputFormat=None, method='Get',
+ startindex=None):
"""Request and return feature data as a file-like object.
Parameters
@@ -140,6 +143,8 @@ class WebFeatureService_1_1_0(WebFeatureService_):
EPSG code to request the data in
outputFormat: string (optional)
Requested response format of the request.
+ startindex: int (optional)
+ Start position to return feature set (paging in combination with maxfeatures)
There are 3 different modes of use
@@ -194,12 +199,14 @@ class WebFeatureService_1_1_0(WebFeatureService_):
request['featureversion'] = str(featureversion)
if maxfeatures is not None:
request['maxfeatures'] = str(maxfeatures)
+ if startindex is not None:
+ request['startindex'] = str(startindex)
if outputFormat is not None:
request["outputFormat"] = outputFormat
data = urlencode(request)
log.debug("Making request: %s?%s" % (base_url, data))
- u = openURL(base_url, data, method)
+ u = openURL(base_url, data, method, timeout=self.timeout)
# check for service exceptions, rewrap, and return
# We're going to assume that anything with a content-length > 32k
diff --git a/owslib/feature/wfs200.py b/owslib/feature/wfs200.py
index 2659d38..b4175ae 100644
--- a/owslib/feature/wfs200.py
+++ b/owslib/feature/wfs200.py
@@ -40,7 +40,7 @@ class WebFeatureService_2_0_0(WebFeatureService_):
Implements IWebFeatureService.
"""
- def __new__(self,url, version, xml, parse_remote_metadata=False):
+ def __new__(self,url, version, xml, parse_remote_metadata=False, timeout=30):
""" overridden __new__ method
@type url: string
@@ -49,10 +49,11 @@ class WebFeatureService_2_0_0(WebFeatureService_):
@param xml: elementtree object
@type parse_remote_metadata: boolean
@param parse_remote_metadata: whether to fully process MetadataURL elements
+ @param timeout: time (in seconds) after which requests should timeout
@return: initialized WebFeatureService_2_0_0 object
"""
obj=object.__new__(self)
- obj.__init__(url, version, xml, parse_remote_metadata)
+ obj.__init__(url, version, xml, parse_remote_metadata, timeout)
return obj
def __getitem__(self,name):
@@ -63,12 +64,13 @@ class WebFeatureService_2_0_0(WebFeatureService_):
raise KeyError, "No content named %s" % name
- def __init__(self, url, version, xml=None, parse_remote_metadata=False):
+ def __init__(self, url, version, xml=None, parse_remote_metadata=False, timeout=30):
"""Initialize."""
if log.isEnabledFor(logging.DEBUG):
log.debug('building WFS %s'%url)
self.url = url
self.version = version
+ self.timeout = timeout
self._capabilities = None
reader = WFSCapabilitiesReader(self.version)
if xml:
@@ -119,12 +121,12 @@ class WebFeatureService_2_0_0(WebFeatureService_):
self.exceptions = [f.text for f \
in self._capabilities.findall('Capability/Exception/Format')]
- def getcapabilities(self, timeout=30):
+ def getcapabilities(self):
"""Request and return capabilities document from the WFS as a
file-like object.
NOTE: this is effectively redundant now"""
reader = WFSCapabilitiesReader(self.version)
- return urlopen(reader.capabilities_url(self.url), timeout=timeout)
+ return urlopen(reader.capabilities_url(self.url), timeout=self.timeout)
def items(self):
'''supports dict-like items() access'''
@@ -135,7 +137,7 @@ class WebFeatureService_2_0_0(WebFeatureService_):
def getfeature(self, typename=None, filter=None, bbox=None, featureid=None,
featureversion=None, propertyname=None, maxfeatures=None,storedQueryID=None, storedQueryParams={},
- method='Get', timeout=30, outputFormat=None):
+ method='Get', outputFormat=None, startindex=None):
"""Request and return feature data as a file-like object.
#TODO: NOTE: have changed property name from ['*'] to None - check the use of this in WFS 2.0
Parameters
@@ -156,10 +158,10 @@ class WebFeatureService_2_0_0(WebFeatureService_):
Maximum number of features to be returned.
method : string
Qualified name of the HTTP DCP method to use.
- timeout : number
- A timeout value (in seconds) for the request.
outputFormat: string (optional)
Requested response format of the request.
+ startindex: int (optional)
+ Start position to return feature set (paging in combination with maxfeatures)
There are 3 different modes of use
@@ -167,7 +169,6 @@ class WebFeatureService_2_0_0(WebFeatureService_):
2) typename and filter (==query) (more expressive)
3) featureid (direct access to known features)
"""
-
url = data = None
if typename and type(typename) == type(""):
typename = [typename]
@@ -175,7 +176,7 @@ class WebFeatureService_2_0_0(WebFeatureService_):
(url) = self.getGETGetFeatureRequest(typename, filter, bbox, featureid,
featureversion, propertyname,
maxfeatures, storedQueryID,
- storedQueryParams, outputFormat)
+ storedQueryParams, outputFormat, 'Get', startindex)
if log.isEnabledFor(logging.DEBUG):
log.debug('GetFeature WFS GET url %s'% url)
else:
@@ -183,7 +184,7 @@ class WebFeatureService_2_0_0(WebFeatureService_):
# If method is 'Post', data will be None here
- u = urlopen(url, data, timeout)
+ u = urlopen(url, data, self.timeout)
# check for service exceptions, rewrap, and return
# We're going to assume that anything with a content-length > 32k
@@ -240,7 +241,7 @@ class WebFeatureService_2_0_0(WebFeatureService_):
return u.read()
- def _getStoredQueries(self, timeout=30):
+ def _getStoredQueries(self):
''' gets descriptions of the stored queries available on the server '''
sqs=[]
#This method makes two calls to the WFS - one ListStoredQueries, and one DescribeStoredQueries. The information is then
@@ -255,7 +256,7 @@ class WebFeatureService_2_0_0(WebFeatureService_):
request = {'service': 'WFS', 'version': self.version, 'request': 'ListStoredQueries'}
encoded_request = urlencode(request)
- u = urlopen(base_url, data=encoded_request, timeout=timeout)
+ u = urlopen(base_url, data=encoded_request, timeout=self.timeout)
tree=etree.fromstring(u.read())
tempdict={}
for sqelem in tree[:]:
@@ -275,7 +276,7 @@ class WebFeatureService_2_0_0(WebFeatureService_):
base_url = self.url
request = {'service': 'WFS', 'version': self.version, 'request': 'DescribeStoredQueries'}
encoded_request = urlencode(request)
- u = urlopen(base_url, data=encoded_request, timeout=timeout)
+ u = urlopen(base_url, data=encoded_request, timeout=to)
tree=etree.fromstring(u.read())
tempdict2={}
for sqelem in tree[:]:
diff --git a/owslib/fes.py b/owslib/fes.py
index 5fb9816..d69b095 100644
--- a/owslib/fes.py
+++ b/owslib/fes.py
@@ -104,7 +104,7 @@ class FilterRequest(object):
return self._root
- def setConstraint(self, constraint):
+ def setConstraint(self, constraint, tostring=False):
"""
Construct and process a GetRecords request
@@ -112,12 +112,17 @@ class FilterRequest(object):
----------
- constraint: An OgcExpression object
+ - tostring (optional): return as string
"""
self._root.append(constraint.toXML())
+
+ if tostring:
+ return util.element_to_string(self._root, xml_declaration=False)
+
return self._root
- def setConstraintList(self, constraints):
+ def setConstraintList(self, constraints, tostring=False):
"""
Construct and process a GetRecords request
@@ -135,15 +140,20 @@ class FilterRequest(object):
[[a,b],[c],[d],[e]] or [[a,b],c,d,e]
(a && b) || c || d || e
+ - tostring (optional): return as string
"""
ors = []
if len(constraints) == 1:
if isinstance(constraints[0], OgcExpression):
- return self.setConstraint(constraints[0])
+ flt = self.setConstraint(constraints[0])
else:
self._root.append(And(operations=constraints[0]).toXML())
- return self._root
+ flt = self._root
+ if tostring:
+ return util.element_to_string(flt, xml_declaration=False)
+ else:
+ return flt
for c in constraints:
if isinstance(c, OgcExpression):
@@ -159,6 +169,10 @@ class FilterRequest(object):
ors.append(And(operations=ands))
self._root.append(Or(operations=ors).toXML())
+
+ if tostring:
+ return util.element_to_string(self._root, xml_declaration=False)
+
return self._root
@@ -340,12 +354,15 @@ class PropertyIsBetween(OgcExpression):
class BBox(OgcExpression):
"""Construct a BBox, two pairs of coordinates (west-south and east-north)"""
- def __init__(self, bbox):
+ def __init__(self, bbox, crs=None):
self.bbox = bbox
+ self.crs = crs
def toXML(self):
tmp = etree.Element(util.nspath_eval('ogc:BBOX', namespaces))
etree.SubElement(tmp, util.nspath_eval('ogc:PropertyName', namespaces)).text = 'ows:BoundingBox'
tmp2 = etree.SubElement(tmp, util.nspath_eval('gml:Envelope', namespaces))
+ if self.crs is not None:
+ tmp2.set('srsName', self.crs)
etree.SubElement(tmp2, util.nspath_eval('gml:lowerCorner', namespaces)).text = '%s %s' % (self.bbox[0], self.bbox[1])
etree.SubElement(tmp2, util.nspath_eval('gml:upperCorner', namespaces)).text = '%s %s' % (self.bbox[2], self.bbox[3])
return tmp
@@ -390,3 +407,4 @@ class Not(UnaryLogicOpType):
def __init__(self, operations):
super(Not,self).__init__('ogc:Not', operations)
+
diff --git a/owslib/swe/observation/sos100.py b/owslib/swe/observation/sos100.py
index cc070df..698c53a 100644
--- a/owslib/swe/observation/sos100.py
+++ b/owslib/swe/observation/sos100.py
@@ -30,7 +30,7 @@ class SensorObservationService_1_0_0(object):
def __getitem__(self,id):
''' check contents dictionary to allow dict like access to service observational offerings'''
- if name in self.__getattribute__('contents').keys():
+ if id in self.__getattribute__('contents').keys():
return self.__getattribute__('contents')[id]
else:
raise KeyError, "No Observational Offering with id: %s" % id
@@ -67,17 +67,17 @@ class SensorObservationService_1_0_0(object):
raise KeyError("No operation named %s" % name)
def _build_metadata(self):
- """
+ """
Set up capabilities metadata objects
"""
# ows:ServiceIdentification metadata
service_id_element = self._capabilities.find(nspath_eval('ows:ServiceIdentification', namespaces))
self.identification = ows.ServiceIdentification(service_id_element)
-
+
# ows:ServiceProvider metadata
service_provider_element = self._capabilities.find(nspath_eval('ows:ServiceProvider', namespaces))
self.provider = ows.ServiceProvider(service_provider_element)
-
+
# ows:OperationsMetadata metadata
self.operations=[]
for elem in self._capabilities.findall(nspath_eval('ows:OperationsMetadata/ows:Operation', namespaces)):
@@ -115,7 +115,7 @@ class SensorObservationService_1_0_0(object):
assert isinstance(procedure, str)
request['procedure'] = procedure
-
+
url_kwargs = {}
if 'timeout' in kwargs:
url_kwargs['timeout'] = kwargs.pop('timeout') # Client specified timeout value
@@ -124,13 +124,13 @@ class SensorObservationService_1_0_0(object):
if kwargs:
for kw in kwargs:
request[kw]=kwargs[kw]
-
- data = urlencode(request)
+
+ data = urlencode(request)
response = openURL(base_url, data, method, username=self.username, password=self.password, **url_kwargs).read()
-
+
tr = etree.fromstring(response)
@@ -176,7 +176,7 @@ class SensorObservationService_1_0_0(object):
# Optional Fields
if eventTime is not None:
request['eventTime'] = eventTime
-
+
url_kwargs = {}
if 'timeout' in kwargs:
url_kwargs['timeout'] = kwargs.pop('timeout') # Client specified timeout value
@@ -185,7 +185,7 @@ class SensorObservationService_1_0_0(object):
for kw in kwargs:
request[kw]=kwargs[kw]
- data = urlencode(request)
+ data = urlencode(request)
response = openURL(base_url, data, method, username=self.username, password=self.password, **kwargs).read()
try:
@@ -193,13 +193,13 @@ class SensorObservationService_1_0_0(object):
if tr.tag == nspath_eval("ows:ExceptionReport", namespaces):
raise ows.ExceptionReport(tr)
else:
- return response
+ return response
except ows.ExceptionReport:
raise
except BaseException:
return response
- def get_operation_by_name(self, name):
+ def get_operation_by_name(self, name):
"""
Return a Operation item by name, case insensitive
"""
@@ -266,7 +266,7 @@ class SosObservationOffering(object):
def __str__(self):
return 'Offering id: %s, name: %s' % (self.id, self.name)
-
+
class SosCapabilitiesReader(object):
def __init__(self, version="1.0.0", url=None, username=None, password=None):
self.version = version
@@ -316,4 +316,3 @@ class SosCapabilitiesReader(object):
if not isinstance(st, str):
raise ValueError("String must be of type string, not %s" % type(st))
return etree.fromstring(st)
-
diff --git a/owslib/swe/observation/sos200.py b/owslib/swe/observation/sos200.py
index 0cf2bb2..a306dcc 100644
--- a/owslib/swe/observation/sos200.py
+++ b/owslib/swe/observation/sos200.py
@@ -32,7 +32,7 @@ class SensorObservationService_2_0_0(object):
def __getitem__(self,id):
''' check contents dictionary to allow dict like access to service observational offerings'''
- if name in self.__getattribute__('contents').keys():
+ if id in self.__getattribute__('contents').keys():
return self.__getattribute__('contents')[id]
else:
raise KeyError, "No Observational Offering with id: %s" % id
@@ -56,8 +56,8 @@ class SensorObservationService_2_0_0(object):
# Avoid building metadata if the response is an Exception
se = self._capabilities.find(nspath_eval('ows:ExceptionReport', namespaces))
- if se is not None:
- raise ows.ExceptionReport(se)
+ if se is not None:
+ raise ows.ExceptionReport(se)
# build metadata objects
self._build_metadata()
@@ -70,17 +70,17 @@ class SensorObservationService_2_0_0(object):
raise KeyError("No operation named %s" % name)
def _build_metadata(self):
- """
+ """
Set up capabilities metadata objects
"""
# ows:ServiceIdentification metadata
service_id_element = self._capabilities.find(nspath_eval('ows:ServiceIdentification', namespaces))
self.identification = ows.ServiceIdentification(service_id_element)
-
+
# ows:ServiceProvider metadata
service_provider_element = self._capabilities.find(nspath_eval('ows:ServiceProvider', namespaces))
self.provider = ows.ServiceProvider(service_provider_element)
-
+
# ows:OperationsMetadata metadata
self.operations= []
for elem in self._capabilities.findall(nspath_eval('ows:OperationsMetadata/ows:Operation', namespaces)):
@@ -118,7 +118,7 @@ class SensorObservationService_2_0_0(object):
assert isinstance(procedure, str)
request['procedure'] = procedure
-
+
url_kwargs = {}
if 'timeout' in kwargs:
url_kwargs['timeout'] = kwargs.pop('timeout') # Client specified timeout value
@@ -127,8 +127,8 @@ class SensorObservationService_2_0_0(object):
if kwargs:
for kw in kwargs:
request[kw]=kwargs[kw]
-
- data = urlencode(request)
+
+ data = urlencode(request)
response = openURL(base_url, data, method, username=self.username, password=self.password, **url_kwargs).read()
tr = etree.fromstring(response)
@@ -155,7 +155,7 @@ class SensorObservationService_2_0_0(object):
anything else e.g. vendor specific parameters
"""
- base_url = self.get_operation_by_name('GetObservation').methods[method]['url']
+ base_url = self.get_operation_by_name('GetObservation').methods[method]['url']
request = {'service': 'SOS', 'version': self.version, 'request': 'GetObservation'}
@@ -172,7 +172,7 @@ class SensorObservationService_2_0_0(object):
# Optional Fields
if eventTime is not None:
request['temporalFilter'] = eventTime
-
+
url_kwargs = {}
if 'timeout' in kwargs:
url_kwargs['timeout'] = kwargs.pop('timeout') # Client specified timeout value
@@ -181,7 +181,7 @@ class SensorObservationService_2_0_0(object):
for kw in kwargs:
request[kw]=kwargs[kw]
- data = urlencode(request)
+ data = urlencode(request)
response = openURL(base_url, data, method, username=self.username, password=self.password, **url_kwargs).read()
try:
@@ -189,13 +189,13 @@ class SensorObservationService_2_0_0(object):
if tr.tag == nspath_eval("ows:ExceptionReport", namespaces):
raise ows.ExceptionReport(tr)
else:
- return response
+ return response
except ows.ExceptionReport:
raise
except BaseException:
return response
- def get_operation_by_name(self, name):
+ def get_operation_by_name(self, name):
"""
Return a Operation item by name, case insensitive
"""
@@ -262,7 +262,7 @@ class SosObservationOffering(object):
def __str__(self):
return 'Offering id: %s, name: %s' % (self.id, self.name)
-
+
class SosCapabilitiesReader(object):
def __init__(self, version="2.0.0", url=None, username=None, password=None):
self.version = version
@@ -312,4 +312,3 @@ class SosCapabilitiesReader(object):
if not isinstance(st, str):
raise ValueError("String must be of type string, not %s" % type(st))
return etree.fromstring(st)
-
diff --git a/owslib/util.py b/owslib/util.py
index d700892..1b36730 100644
--- a/owslib/util.py
+++ b/owslib/util.py
@@ -390,28 +390,40 @@ def http_post(url=None, request=None, lang='en-US', timeout=10, username=None, p
return response
-def element_to_string(element, encoding=None):
+def element_to_string(element, encoding=None, xml_declaration=False):
"""
Returns a string from a XML object
Parameters
----------
- - xml: etree Element
+ - element: etree Element
- encoding (optional): encoding in string form. 'utf-8', 'ISO-8859-1', etc.
+ - xml_declaration (optional): whether to include xml declaration
"""
+
+ output = None
+
if encoding is None:
encoding = "ISO-8859-1"
if etree.__name__ == 'lxml.etree':
- if encoding in ['unicode', 'utf-8']:
- return '<?xml version="1.0" encoding="utf-8" standalone="no"?>\n%s' % \
- etree.tostring(element, encoding='unicode')
+ if xml_declaration:
+ if encoding in ['unicode', 'utf-8']:
+ output = '<?xml version="1.0" encoding="utf-8" standalone="no"?>\n%s' % \
+ etree.tostring(element, encoding='unicode')
+ else:
+ output = etree.tostring(element, encoding=encoding, xml_declaration=True)
else:
- return etree.tostring(element, encoding=encoding, xml_declaration=True)
+ output = etree.tostring(element)
else:
- return '<?xml version="1.0" encoding="%s" standalone="no"?>\n%s' % (encoding,
- etree.tostring(element, encoding=encoding))
+ if xml_declaration:
+ output = '<?xml version="1.0" encoding="%s" standalone="no"?>\n%s' % (encoding,
+ etree.tostring(element, encoding=encoding))
+ else:
+ output = etree.tostring(element)
+
+ return output
def xml2string(xml):
@@ -576,3 +588,4 @@ try: # 2.7
except: # 2.6
from ordereddict import OrderedDict
+
diff --git a/owslib/wfs.py b/owslib/wfs.py
index 3c4fc4b..3f2b6cd 100644
--- a/owslib/wfs.py
+++ b/owslib/wfs.py
@@ -14,7 +14,8 @@ Web Feature Server (WFS) methods and metadata. Factory function.
"""
from feature import wfs100, wfs110, wfs200
-def WebFeatureService(url, version='1.0.0', xml=None, parse_remote_metadata=False):
+def WebFeatureService(url, version='1.0.0', xml=None, parse_remote_metadata=False,
+ timeout=30):
''' wfs factory function, returns a version specific WebFeatureService object
@type url: string
@@ -23,12 +24,16 @@ def WebFeatureService(url, version='1.0.0', xml=None, parse_remote_metadata=Fals
@param xml: elementtree object
@type parse_remote_metadata: boolean
@param parse_remote_metadata: whether to fully process MetadataURL elements
+ @param timeout: time (in seconds) after which requests should timeout
@return: initialized WebFeatureService_2_0_0 object
'''
if version in ['1.0', '1.0.0']:
- return wfs100.WebFeatureService_1_0_0(url, version, xml, parse_remote_metadata)
+ return wfs100.WebFeatureService_1_0_0(url, version, xml, parse_remote_metadata,
+ timeout=timeout)
elif version in ['1.1', '1.1.0']:
- return wfs110.WebFeatureService_1_1_0(url, version, xml, parse_remote_metadata)
+ return wfs110.WebFeatureService_1_1_0(url, version, xml, parse_remote_metadata,
+ timeout=timeout)
elif version in ['2.0', '2.0.0']:
- return wfs200.WebFeatureService_2_0_0(url, version, xml, parse_remote_metadata)
+ return wfs200.WebFeatureService_2_0_0(url, version, xml, parse_remote_metadata,
+ timeout=timeout)
diff --git a/owslib/wms.py b/owslib/wms.py
index 045c388..e726b5c 100644
--- a/owslib/wms.py
+++ b/owslib/wms.py
@@ -1,4 +1,4 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: iso-8859-15 -*-
# =============================================================================
# Copyright (c) 2004, 2006 Sean C. Gillies
# Copyright (c) 2005 Nuxeo SARL <http://nuxeo.com>
@@ -366,7 +366,8 @@ class ContentMetadata:
sh = elem.find('ScaleHint')
self.scaleHint = None
if sh is not None:
- self.scaleHint = {'min': sh.attrib['min'], 'max': sh.attrib['max']}
+ if 'min' in sh.attrib and 'max' in sh.attrib:
+ self.scaleHint = {'min': sh.attrib['min'], 'max': sh.attrib['max']}
attribution = elem.find('Attribution')
if attribution is not None:
diff --git a/owslib/wmts.py b/owslib/wmts.py
index a402334..eff4e04 100644
--- a/owslib/wmts.py
+++ b/owslib/wmts.py
@@ -16,13 +16,16 @@
Abstract
--------
-The wmts module of the OWSlib package provides client-side functionality for fetching tiles from an OGC Web Map Tile Service (WMTS)
+The wmts module of the OWSlib package provides client-side functionality
+for fetching tiles from an OGC Web Map Tile Service (WMTS)
Disclaimer
----------
-PLEASE NOTE: the owslib wmts module should be considered in early-beta state: it has been tested against only one WMTS server (NASA EODSIS).
-More extensive testing is needed and feedback (to bradh at frogmouth.net) would be appreciated.
+PLEASE NOTE: the owslib wmts module should be considered in early-beta
+state: it has been tested against only one WMTS server (NASA EODSIS).
+More extensive testing is needed and feedback (to bradh at frogmouth.net)
+would be appreciated.
"""
@@ -37,16 +40,48 @@ from iso import MD_Metadata
from ows import ServiceProvider, ServiceIdentification, OperationsMetadata
+_OWS_NS = '{http://www.opengis.net/ows/1.1}'
_WMTS_NS = '{http://www.opengis.net/wmts/1.0}'
+_XLINK_NS = '{http://www.w3.org/1999/xlink}'
+
+_ABSTRACT_TAG = _OWS_NS + 'Abstract'
+_IDENTIFIER_TAG = _OWS_NS + 'Identifier'
+_LOWER_CORNER_TAG = _OWS_NS + 'LowerCorner'
+_OPERATIONS_METADATA_TAG = _OWS_NS + 'OperationsMetadata'
+_SERVICE_IDENTIFICATION_TAG = _OWS_NS + 'ServiceIdentification'
+_SERVICE_PROVIDER_TAG = _OWS_NS + 'ServiceProvider'
+_SUPPORTED_CRS_TAG = _OWS_NS + 'SupportedCRS'
+_TITLE_TAG = _OWS_NS + 'Title'
+_UPPER_CORNER_TAG = _OWS_NS + 'UpperCorner'
+_WGS84_BOUNDING_BOX_TAG = _OWS_NS + 'WGS84BoundingBox'
+
+_CONTENTS_TAG = _WMTS_NS + 'Contents'
+_FORMAT_TAG = _WMTS_NS + 'Format'
+_INFO_FORMAT_TAG = _WMTS_NS + 'InfoFormat'
+_LAYER_TAG = _WMTS_NS + 'Layer'
+_LAYER_REF_TAG = _WMTS_NS + 'LayerRef'
+_MATRIX_HEIGHT_TAG = _WMTS_NS + 'MatrixHeight'
+_MATRIX_WIDTH_TAG = _WMTS_NS + 'MatrixWidth'
+_MAX_TILE_COL_TAG = _WMTS_NS + 'MaxTileCol'
+_MAX_TILE_ROW_TAG = _WMTS_NS + 'MaxTileRow'
+_MIN_TILE_COL_TAG = _WMTS_NS + 'MinTileCol'
+_MIN_TILE_ROW_TAG = _WMTS_NS + 'MinTileRow'
+_RESOURCE_URL_TAG = _WMTS_NS + 'ResourceURL'
+_SCALE_DENOMINATOR_TAG = _WMTS_NS + 'ScaleDenominator'
+_SERVICE_METADATA_URL_TAG = _WMTS_NS + 'ServiceMetadataURL'
+_STYLE_TAG = _WMTS_NS + 'Style'
+_THEME_TAG = _WMTS_NS + 'Theme'
+_THEMES_TAG = _WMTS_NS + 'Themes'
+_TILE_HEIGHT_TAG = _WMTS_NS + 'TileHeight'
_TILE_MATRIX_SET_LINK_TAG = _WMTS_NS + 'TileMatrixSetLink'
_TILE_MATRIX_SET_TAG = _WMTS_NS + 'TileMatrixSet'
_TILE_MATRIX_SET_LIMITS_TAG = _WMTS_NS + 'TileMatrixSetLimits'
_TILE_MATRIX_LIMITS_TAG = _WMTS_NS + 'TileMatrixLimits'
_TILE_MATRIX_TAG = _WMTS_NS + 'TileMatrix'
-_MIN_TILE_ROW_TAG = _WMTS_NS + 'MinTileRow'
-_MAX_TILE_ROW_TAG = _WMTS_NS + 'MaxTileRow'
-_MIN_TILE_COL_TAG = _WMTS_NS + 'MinTileCol'
-_MAX_TILE_COL_TAG = _WMTS_NS + 'MaxTileCol'
+_TILE_WIDTH_TAG = _WMTS_NS + 'TileWidth'
+_TOP_LEFT_CORNER_TAG = _WMTS_NS + 'TopLeftCorner'
+
+_HREF_TAG = _XLINK_NS + 'href'
class ServiceException(Exception):
@@ -75,35 +110,57 @@ class WebMapTileService(object):
Implements IWebMapService.
"""
- def __getitem__(self,name):
- ''' check contents dictionary to allow dict like access to service layers'''
+ def __getitem__(self, name):
+ '''Check contents dictionary to allow dict like access to
+ service layers'''
if name in self.__getattribute__('contents').keys():
return self.__getattribute__('contents')[name]
else:
- raise KeyError, "No content named %s" % name
+ raise KeyError("No content named %s" % name)
+
+ def __init__(self, url, version='1.0.0', xml=None, username=None,
+ password=None, parse_remote_metadata=False,
+ vendor_kwargs=None):
+ """Initialize.
+ Parameters
+ ----------
+ url : string
+ Base URL for the WMTS service.
+ version : string
+ Optional WMTS version. Defaults to '1.0.0'.
+ xml : string
+ Optional XML content to use as the content for the initial
+ GetCapabilities request. Typically only used for testing.
+ username : string
+ Optional user name for authentication.
+ password : string
+ Optional password for authentication.
+ parse_remote_metadata: string
+ Currently unused.
+ vendor_kwargs : dict
+ Optional vendor-specific parameters to be included in all
+ requests.
- def __init__(self, url, version='1.0.0', xml=None,
- username=None, password=None, parse_remote_metadata=False
- ):
- """Initialize."""
+ """
self.url = url
self.username = username
self.password = password
self.version = version
+ self.vendor_kwargs = vendor_kwargs
self._capabilities = None
# Authentication handled by Reader
- reader = WMTSCapabilitiesReader(
- self.version, url=self.url, un=self.username, pw=self.password
- )
+ reader = WMTSCapabilitiesReader(self.version, url=self.url,
+ un=self.username, pw=self.password)
if xml: # read from stored xml
self._capabilities = reader.readString(xml)
else: # read from server
- self._capabilities = reader.read(self.url)
+ self._capabilities = reader.read(self.url, self.vendor_kwargs)
- # avoid building capabilities metadata if the response is a ServiceExceptionReport
+ # Avoid building capabilities metadata if the response is a
+ # ServiceExceptionReport.
# TODO: check if this needs a namespace
se = self._capabilities.find('ServiceException')
if se is not None:
@@ -118,70 +175,78 @@ class WebMapTileService(object):
reader = WMTSCapabilitiesReader(
self.version, url=self.url, un=self.username, pw=self.password
)
- self._capabilities = ServiceMetadata(reader.read(self.url))
+ xml = reader.read(self.url, self.vendor_kwargs)
+ self._capabilities = ServiceMetadata(xml)
return self._capabilities
def _buildMetadata(self, parse_remote_metadata=False):
''' set up capabilities metadata objects '''
- #serviceIdentification metadata
- serviceident=self._capabilities.find('{http://www.opengis.net/ows/1.1}ServiceIdentification')
- self.identification=ServiceIdentification(serviceident)
+ # serviceIdentification metadata
+ serviceident = self._capabilities.find(_SERVICE_IDENTIFICATION_TAG)
+ self.identification = ServiceIdentification(serviceident)
- #serviceProvider metadata
- serviceprov=self._capabilities.find('{http://www.opengis.net/ows/1.1}ServiceProvider')
- self.provider=ServiceProvider(serviceprov)
+ # serviceProvider metadata
+ serviceprov = self._capabilities.find(_SERVICE_PROVIDER_TAG)
+ self.provider = ServiceProvider(serviceprov)
- #serviceOperations metadata
- self.operations=[]
- for elem in self._capabilities.find('{http://www.opengis.net/ows/1.1}OperationsMetadata')[:]:
+ # serviceOperations metadata
+ self.operations = []
+ for elem in self._capabilities.find(_OPERATIONS_METADATA_TAG)[:]:
self.operations.append(OperationsMetadata(elem))
- #serviceContents metadata: our assumption is that services use a top-level
- #layer as a metadata organizer, nothing more.
- self.contents={}
- caps = self._capabilities.find('{http://www.opengis.net/wmts/1.0}Contents')
+ # serviceContents metadata: our assumption is that services use
+ # a top-level layer as a metadata organizer, nothing more.
+ self.contents = {}
+ caps = self._capabilities.find(_CONTENTS_TAG)
def gather_layers(parent_elem, parent_metadata):
- for index, elem in enumerate(parent_elem.findall('{http://www.opengis.net/wmts/1.0}Layer')):
- cm = ContentMetadata(elem, parent=parent_metadata, index=index+1, parse_remote_metadata=parse_remote_metadata)
+ for index, elem in enumerate(parent_elem.findall(_LAYER_TAG)):
+ cm = ContentMetadata(
+ elem, parent=parent_metadata, index=index+1,
+ parse_remote_metadata=parse_remote_metadata)
if cm.id:
if cm.id in self.contents:
- raise KeyError('Content metadata for layer "%s" already exists' % cm.id)
+ raise KeyError('Content metadata for layer "%s" '
+ 'already exists' % cm.id)
self.contents[cm.id] = cm
gather_layers(elem, cm)
gather_layers(caps, None)
self.tilematrixsets = {}
- for elem in caps.findall('{http://www.opengis.net/wmts/1.0}TileMatrixSet'):
+ for elem in caps.findall(_TILE_MATRIX_SET_TAG):
tms = TileMatrixSet(elem)
if tms.identifier:
if tms.identifier in self.tilematrixsets:
- raise KeyError('TileMatrixSet with identifier "%s" already exists' % tms.identifier)
+ raise KeyError('TileMatrixSet with identifier "%s" '
+ 'already exists' % tms.identifier)
self.tilematrixsets[tms.identifier] = tms
self.themes = {}
- for elem in self._capabilities.findall('{http://www.opengis.net/wmts/1.0}Themes/{http://www.opengis.net/wmts/1.0}Theme'):
+ for elem in self._capabilities.findall(_THEMES_TAG + '/' + _THEME_TAG):
theme = Theme(elem)
if theme.identifier:
if theme.identifier in self.themes:
- raise KeyError('Theme with identifier "%s" already exists' % theme.identifier)
+ raise KeyError('Theme with identifier "%s" already exists'
+ % theme.identifier)
self.themes[theme.identifier] = theme
- serviceMetadataURL = self._capabilities.find('{http://www.opengis.net/wmts/1.0}ServiceMetadataURL')
+ serviceMetadataURL = self._capabilities.find(_SERVICE_METADATA_URL_TAG)
if serviceMetadataURL is not None:
- self.serviceMetadataURL = serviceMetadataURL.attrib['{http://www.w3.org/1999/xlink}href']
+ self.serviceMetadataURL = serviceMetadataURL.attrib[_HREF_TAG]
else:
self.serviceMetadataURL = None
def items(self):
'''supports dict-like items() access'''
- items=[]
+ items = []
for item in self.contents:
- items.append((item,self.contents[item]))
+ items.append((item, self.contents[item]))
return items
- def buildTileRequest(self, layer=None, style=None, format=None, tilematrixset=None, tilematrix=None, row=None, column=None, **kwargs):
+ def buildTileRequest(self, layer=None, style=None, format=None,
+ tilematrixset=None, tilematrix=None, row=None,
+ column=None, **kwargs):
"""Return the URL-encoded parameters for a GetTile request.
Parameters
@@ -252,12 +317,14 @@ TILEMATRIX=6&TILEROW=4&TILECOL=4&FORMAT=image%2Fjpeg'
request.append(('FORMAT', format))
for key, value in kwargs.iteritems():
- request.append(key, value)
+ request.append((key, value))
data = urlencode(request, True)
return data
- def gettile(self, base_url=None, layer=None, style=None, format=None, tilematrixset=None, tilematrix=None, row=None, column=None, **kwargs):
+ def gettile(self, base_url=None, layer=None, style=None, format=None,
+ tilematrixset=None, tilematrix=None, row=None, column=None,
+ **kwargs):
"""Return a tile from the WMTS.
Returns the tile image as a file-like object.
@@ -303,15 +370,27 @@ TILEMATRIX=6&TILEROW=4&TILECOL=4&FORMAT=image%2Fjpeg'
>>> out.close()
"""
- data = self.buildTileRequest(layer, style, format, tilematrixset, tilematrix, row, column, **kwargs)
+ vendor_kwargs = self.vendor_kwargs or {}
+ vendor_kwargs.update(kwargs)
+ data = self.buildTileRequest(layer, style, format, tilematrixset,
+ tilematrix, row, column, **vendor_kwargs)
if base_url is None:
base_url = self.url
try:
- get_verbs = filter(lambda x: x.get('type').lower() == 'get', self.getOperationByName('GetTile').methods)
+ get_verbs = filter(
+ lambda x: x.get('type').lower() == 'get',
+ self.getOperationByName('GetTile').methods)
if len(get_verbs) > 1:
# Filter by constraints
- base_url = next(x for x in filter(list, ([pv.get('url') for const in pv.get('constraints') if 'kvp' in map(lambda x: x.lower(), const.values)] for pv in get_verbs if pv.get('constraints'))))[0]
+ base_url = next(
+ x for x in filter(
+ list,
+ ([pv.get('url')
+ for const in pv.get('constraints')
+ if 'kvp' in map(
+ lambda x: x.lower(), const.values)]
+ for pv in get_verbs if pv.get('constraints'))))[0]
elif len(get_verbs) == 1:
base_url = get_verbs[0].get('url')
except StopIteration:
@@ -341,74 +420,80 @@ TILEMATRIX=6&TILEROW=4&TILECOL=4&FORMAT=image%2Fjpeg'
for item in self.operations:
if item.name == name:
return item
- raise KeyError, "No operation named %s" % name
+ raise KeyError("No operation named %s" % name)
+
class TileMatrixSet(object):
'''Holds one TileMatrixSet'''
def __init__(self, elem):
- if elem.tag != '{http://www.opengis.net/wmts/1.0}TileMatrixSet':
+ if elem.tag != _TILE_MATRIX_SET_TAG:
raise ValueError('%s should be a TileMatrixSet' % (elem,))
- self.identifier = testXMLValue(elem.find('{http://www.opengis.net/ows/1.1}Identifier')).strip()
- self.crs = testXMLValue(elem.find('{http://www.opengis.net/ows/1.1}SupportedCRS')).strip()
- if (self.crs == None) or (self.identifier == None):
+ self.identifier = testXMLValue(elem.find(_IDENTIFIER_TAG)).strip()
+ self.crs = testXMLValue(elem.find(_SUPPORTED_CRS_TAG)).strip()
+ if self.crs is None or self.identifier is None:
raise ValueError('%s incomplete TileMatrixSet' % (elem,))
self.tilematrix = {}
- for tilematrix in elem.findall('{http://www.opengis.net/wmts/1.0}TileMatrix'):
+ for tilematrix in elem.findall(_TILE_MATRIX_TAG):
tm = TileMatrix(tilematrix)
if tm.identifier:
if tm.identifier in self.tilematrix:
- raise KeyError('TileMatrix with identifier "%s" already exists' % tm.identifier)
+ raise KeyError('TileMatrix with identifier "%s" '
+ 'already exists' % tm.identifier)
self.tilematrix[tm.identifier] = tm
+
class TileMatrix(object):
'''Holds one TileMatrix'''
def __init__(self, elem):
- if elem.tag != '{http://www.opengis.net/wmts/1.0}TileMatrix':
+ if elem.tag != _TILE_MATRIX_TAG:
raise ValueError('%s should be a TileMatrix' % (elem,))
- self.identifier = testXMLValue(elem.find('{http://www.opengis.net/ows/1.1}Identifier')).strip()
- sd = testXMLValue(elem.find('{http://www.opengis.net/wmts/1.0}ScaleDenominator'))
+ self.identifier = testXMLValue(elem.find(_IDENTIFIER_TAG)).strip()
+ sd = testXMLValue(elem.find(_SCALE_DENOMINATOR_TAG))
if sd is None:
raise ValueError('%s is missing ScaleDenominator' % (elem,))
self.scaledenominator = float(sd)
- tl = testXMLValue(elem.find('{http://www.opengis.net/wmts/1.0}TopLeftCorner'))
+ tl = testXMLValue(elem.find(_TOP_LEFT_CORNER_TAG))
if tl is None:
raise ValueError('%s is missing TopLeftCorner' % (elem,))
(lon, lat) = tl.split(" ")
self.topleftcorner = (float(lon), float(lat))
- width = testXMLValue(elem.find('{http://www.opengis.net/wmts/1.0}TileWidth'))
- height = testXMLValue(elem.find('{http://www.opengis.net/wmts/1.0}TileHeight'))
+ width = testXMLValue(elem.find(_TILE_WIDTH_TAG))
+ height = testXMLValue(elem.find(_TILE_HEIGHT_TAG))
if (width is None) or (height is None):
- raise ValueError('%s is missing TileWidth and/or TileHeight' % (elem,))
+ msg = '%s is missing TileWidth and/or TileHeight' % (elem,)
+ raise ValueError(msg)
self.tilewidth = int(width)
self.tileheight = int(height)
- mw = testXMLValue(elem.find('{http://www.opengis.net/wmts/1.0}MatrixWidth'))
- mh = testXMLValue(elem.find('{http://www.opengis.net/wmts/1.0}MatrixHeight'))
+ mw = testXMLValue(elem.find(_MATRIX_WIDTH_TAG))
+ mh = testXMLValue(elem.find(_MATRIX_HEIGHT_TAG))
if (mw is None) or (mh is None):
- raise ValueError('%s is missing MatrixWidth and/or MatrixHeight' % (elem,))
+ msg = '%s is missing MatrixWidth and/or MatrixHeight' % (elem,)
+ raise ValueError(msg)
self.matrixwidth = int(mw)
self.matrixheight = int(mh)
+
class Theme:
"""
Abstraction for a WMTS theme
"""
def __init__(self, elem):
- if elem.tag != '{http://www.opengis.net/wmts/1.0}Theme':
+ if elem.tag != _THEME_TAG:
raise ValueError('%s should be a Theme' % (elem,))
- self.identifier = testXMLValue(elem.find('{http://www.opengis.net/ows/1.1}Identifier')).strip()
- title = testXMLValue(elem.find('{http://www.opengis.net/ows/1.1}Title'))
+ self.identifier = testXMLValue(elem.find(_IDENTIFIER_TAG)).strip()
+ title = testXMLValue(elem.find(_TITLE_TAG))
if title is not None:
self.title = title.strip()
else:
self.title = None
- abstract = testXMLValue(elem.find('{http://www.opengis.net/ows/1.1}Abstract'))
+ abstract = testXMLValue(elem.find(_ABSTRACT_TAG))
if abstract is not None:
self.abstract = abstract.strip()
else:
self.abstract = None
self.layerRefs = []
- layerRefs = elem.findall('{http://www.opengis.net/wmts/1.0}LayerRef')
+ layerRefs = elem.findall(_LAYER_REF_TAG)
for layerRef in layerRefs:
if layerRef.text is not None:
self.layerRefs.append(layerRef.text)
@@ -465,9 +550,9 @@ class TileMatrixSetLink(object):
set_limits_elements = link_element.findall(
_TILE_MATRIX_SET_LIMITS_TAG)
if set_limits_elements:
- raise ValueError('Multiple instances of TileMatrixSet'
- ' plus TileMatrixSetLimits in %s' %
- link_element)
+ raise ValueError('Multiple instances of TileMatrixSet'
+ ' plus TileMatrixSetLimits in %s' %
+ link_element)
for matrix_set_element in matrix_set_elements:
uri = matrix_set_element.text.strip()
links.append(TileMatrixSetLink(uri))
@@ -475,12 +560,15 @@ class TileMatrixSetLink(object):
uri = matrix_set_elements[0].text.strip()
tilematrixlimits = {}
- path = '%s/%s' % (_TILE_MATRIX_SET_LIMITS_TAG, _TILE_MATRIX_LIMITS_TAG)
+ path = '%s/%s' % (_TILE_MATRIX_SET_LIMITS_TAG,
+ _TILE_MATRIX_LIMITS_TAG)
for limits_element in link_element.findall(path):
tml = TileMatrixLimits(limits_element)
if tml.tilematrix:
if tml.tilematrix in tilematrixlimits:
- raise KeyError('TileMatrixLimits with tileMatrix "%s" already exists' % tml.tilematrix)
+ msg = ('TileMatrixLimits with tileMatrix "%s" '
+ 'already exists' % tml.tilematrix)
+ raise KeyError(msg)
tilematrixlimits[tml.tilematrix] = tml
links.append(TileMatrixSetLink(uri, tilematrixlimits))
@@ -506,8 +594,9 @@ class ContentMetadata:
Implements IContentMetadata.
"""
- def __init__(self, elem, parent=None, index=0, parse_remote_metadata=False):
- if elem.tag != '{http://www.opengis.net/wmts/1.0}Layer':
+ def __init__(self, elem, parent=None, index=0,
+ parse_remote_metadata=False):
+ if elem.tag != _LAYER_TAG:
raise ValueError('%s should be a Layer' % (elem,))
self.parent = parent
@@ -516,25 +605,26 @@ class ContentMetadata:
else:
self.index = str(index)
- self.id = self.name = testXMLValue(elem.find('{http://www.opengis.net/ows/1.1}Identifier'))
+ self.id = self.name = testXMLValue(elem.find(_IDENTIFIER_TAG))
# title is mandatory property
self.title = None
- title = testXMLValue(elem.find('{http://www.opengis.net/ows/1.1}Title'))
+ title = testXMLValue(elem.find(_TITLE_TAG))
if title is not None:
self.title = title.strip()
- self.abstract = testXMLValue(elem.find('{http://www.opengis.net/ows/1.1}Abstract'))
+ self.abstract = testXMLValue(elem.find(_ABSTRACT_TAG))
# bboxes
- b = elem.find('{http://www.opengis.net/ows/1.1}WGS84BoundingBox')
+ b = elem.find(_WGS84_BOUNDING_BOX_TAG)
self.boundingBox = None
if b is not None:
- lc = b.find("{http://www.opengis.net/ows/1.1}LowerCorner")
- uc = b.find("{http://www.opengis.net/ows/1.1}UpperCorner")
+ lc = b.find(_LOWER_CORNER_TAG)
+ uc = b.find(_UPPER_CORNER_TAG)
ll = [float(s) for s in lc.text.split()]
ur = [float(s) for s in uc.text.split()]
- self.boundingBoxWGS84 = (ll[0],ll[1],ur[0],ur[1])
- # TODO: there is probably some more logic here, and it should probably be shared code
+ self.boundingBoxWGS84 = (ll[0], ll[1], ur[0], ur[1])
+ # TODO: there is probably some more logic here, and it should
+ # probably be shared code
self._tilematrixsets = [f.text.strip() for f in
elem.findall(_TILE_MATRIX_SET_LINK_TAG + '/' +
@@ -552,32 +642,32 @@ class ContentMetadata:
self.tilematrixsetlinks[tmsl.tilematrixset] = tmsl
self.resourceURLs = []
- for resourceURL in elem.findall('{http://www.opengis.net/wmts/1.0}ResourceURL'):
+ for resourceURL in elem.findall(_RESOURCE_URL_TAG):
resource = {}
for attrib in ['format', 'resourceType', 'template']:
resource[attrib] = resourceURL.attrib[attrib]
self.resourceURLs.append(resource)
- #Styles
+ # Styles
self.styles = {}
- for s in elem.findall('{http://www.opengis.net/wmts/1.0}Style'):
+ for s in elem.findall(_STYLE_TAG):
style = {}
isdefaulttext = s.attrib.get('isDefault')
style['isDefault'] = (isdefaulttext == "true")
- identifier = s.find('{http://www.opengis.net/ows/1.1}Identifier')
+ identifier = s.find(_IDENTIFIER_TAG)
if identifier is None:
raise ValueError('%s missing identifier' % (s,))
- title = s.find('{http://www.opengis.net/ows/1.1}Title')
+ title = s.find(_TITLE_TAG)
if title is not None:
style['title'] = title.text
self.styles[identifier.text] = style
- self.formats = [f.text for f in elem.findall('{http://www.opengis.net/wmts/1.0}Format')]
+ self.formats = [f.text for f in elem.findall(_FORMAT_TAG)]
- self.infoformats = [f.text for f in elem.findall('{http://www.opengis.net/wmts/1.0}InfoFormat')]
+ self.infoformats = [f.text for f in elem.findall(_INFO_FORMAT_TAG)]
self.layers = []
- for child in elem.findall('{http://www.opengis.net/wmts/1.0}Layer'):
+ for child in elem.findall(_LAYER_TAG):
self.layers.append(ContentMetadata(child, self))
@property
@@ -606,37 +696,41 @@ class WMTSCapabilitiesReader:
self.username = un
self.password = pw
- def capabilities_url(self, service_url):
+ def capabilities_url(self, service_url, vendor_kwargs=None):
"""Return a capabilities url
"""
- qs = []
- if service_url.find('?') != -1:
- qs = urlparse.parse_qsl(service_url.split('?')[1])
-
- params = [x[0] for x in qs]
-
- if 'service' not in params:
- qs.append(('service', 'WMTS'))
- if 'request' not in params:
- qs.append(('request', 'GetCapabilities'))
- if 'version' not in params:
- qs.append(('version', self.version))
-
- urlqs = urlencode(tuple(qs))
- return service_url.split('?')[0] + '?' + urlqs
-
- def read(self, service_url):
+ # Ensure the 'service', 'request', and 'version' parameters,
+ # and any vendor-specific parameters are included in the URL.
+ pieces = urlparse.urlparse(service_url)
+ args = urlparse.parse_qs(pieces.query)
+ if 'service' not in args:
+ args['service'] = 'WMTS'
+ if 'request' not in args:
+ args['request'] = 'GetCapabilities'
+ if 'version' not in args:
+ args['version'] = self.version
+ if vendor_kwargs:
+ args.update(vendor_kwargs)
+ query = urlencode(args, doseq=True)
+ pieces = urlparse.ParseResult(pieces.scheme, pieces.netloc,
+ pieces.path, pieces.params,
+ query, pieces.fragment)
+ return urlparse.urlunparse(pieces)
+
+ def read(self, service_url, vendor_kwargs=None):
"""Get and parse a WMTS capabilities document, returning an
elementtree instance
service_url is the base url, to which is appended the service,
- version, and request parameters
+ version, and request parameters. Optional vendor-specific
+ parameters can also be supplied as a dict.
"""
- getcaprequest = self.capabilities_url(service_url)
+ getcaprequest = self.capabilities_url(service_url, vendor_kwargs)
- #now split it up again to use the generic openURL function...
- spliturl=getcaprequest.split('?')
- u = openURL(spliturl[0], spliturl[1], method='Get', username = self.username, password = self.password)
+ # now split it up again to use the generic openURL function...
+ spliturl = getcaprequest.split('?')
+ u = openURL(spliturl[0], spliturl[1], method='Get',
+ username=self.username, password=self.password)
return etree.fromstring(u.read())
def readString(self, st):
@@ -645,5 +739,6 @@ class WMTSCapabilitiesReader:
string should be an XML capabilities document
"""
if not isinstance(st, str):
- raise ValueError("String must be of type string, not %s" % type(st))
+ msg = 'String must be of type string, not %s' % type(st)
+ raise ValueError(msg)
return etree.fromstring(st)
diff --git a/owslib/wps.py b/owslib/wps.py
index 3479fab..0929c31 100644
--- a/owslib/wps.py
+++ b/owslib/wps.py
@@ -808,6 +808,7 @@ class InputOutput(object):
self.supportedValues = []
self.defaultValue = None
self.dataType = None
+ self.anyValue = False
def _parseData(self, element):
"""
@@ -856,7 +857,7 @@ class InputOutput(object):
elif subElement.tag.endswith('DefaultValue'):
self.defaultValue = getTypedValue(self.dataType, subElement.text)
elif subElement.tag.endswith('AnyValue'):
- self.allowedValues.append( getTypedValue(self.dataType, 'AnyValue') )
+ self.anyValue = True
def _parseComplexData(self, element, complexDataElementName):
@@ -1364,6 +1365,8 @@ def printInputOutput(value, indent=''):
print '%s identifier=%s, title=%s, abstract=%s, data type=%s' % (indent, value.identifier, value.title, value.abstract, value.dataType)
for val in value.allowedValues:
print '%s Allowed Value: %s' % (indent, printValue(val))
+ if value.anyValue:
+ print ' Any value allowed'
for val in value.supportedValues:
print '%s Supported Value: %s' % (indent, printValue(val))
print '%s Default Value: %s ' % (indent, printValue(value.defaultValue))
diff --git a/requirements-dev.txt b/requirements-dev.txt
index e2ad8c1..d51e4fc 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -1,3 +1,4 @@
+pep8
pytest
pytest-cov
Pillow
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/owslib.git
More information about the Pkg-grass-devel
mailing list