Skip to content
Commits on Source (4)
language: python
python:
- "2.7"
- "3.5"
- "3.6"
# Enable 3.7 without globally enabling sudo and dist: xenial for other build jobs
......@@ -24,8 +23,7 @@ install:
- if [ "$LXML" == "true" ]; then pip install lxml; fi
script:
- python -m pytest
- flake8 owslib/wmts.py
- flake8 owslib/wps.py
- flake8 owslib
after_success:
- coveralls
notifications:
......
Changes
=======
0.18.0 (2019-06-24)
-------------------
This release includes initial support for the evolving OGC API - Features
standard (aka WFS 3), which represents a clean break from the traditional
design patterns of OGC interface specifications. This release also includes
a refactoring of authentication support into a common approach for all parts of the codebase to use.
Thanks to Eric Spitler for this enhanced functionality!
Users are strongly encouraged to use OWSLib via Python 3 as Python 2 support
(Travis, python-six) will be removed in the future.
A full list of commits for 0.18.0 can be found at:
https://github.com/geopython/OWSLib/commits/0.18.0
- NEW: WFS 3 initial implementation
- NEW: add Authentication framework (eric-spitler)
- WPS:
* add process properties, percentCompleted (cehbrecht)
* add reference attributes (enolfc)
* add support for multi process processes (huard)
- OWS: add support for crs and dimension (saimeCS)
0.17.1 (2019-01-12)
-------------------
Bugfix release for issues in WPS and WMS.
A full list of commits for 0.17.1 can be found at:
https://github.com/geopython/OWSLib/commits/0.17.1
0.17.0 (2018-09-04)
-------------------
- Fixed test-suite and converted doctests to unit-tests (#339).
- Support for OWS Context (#483 thanks @allixender)
This release provides numerous fixes, enhancements and re-engineering
of OWSLib's test framework.
A full list of commits for 0.17.0 can be found at:
https://github.com/geopython/OWSLib/commits/0.17.0
- NEW: OWS Context implementation (#483 allixender)
- ISO:
* Added MD_LegalConstraints to uselimitation xpath (m431m)
* Fix ISO metadata parsing for empty gmd:featureCatalogueCitation. (Roel)
- OWS:
* Improve remote metadata parsing (Roel)
* Allow the lack of optional ows:ServiceProvider (mhugo)
- WPS:
* add headers, cert options (cehbrecht)
* add lineage to execute (cehbrecht)
- WMTS/TMS: replaced ServiceMetadata (cehbrecht)
- SOS: fix encoding error (cehbrecht)
- tests: move away from doctests (#339 cehbrecht)
- overall codebase: move from pep8 to flake8
- Support for WCS 2.0.0 and 2.0.1 (#430, thanks @doclements)
- numerous bug-fixes, especially for WPS.
0.16.0 (2017-12-21)
-------------------
- drop Python 2.6 support
- WFS: get schema auth params (karakostis)
- WFS: add sortby to GetFeature requests (drnextgis)
- CSW: add ows namespace to bounding box queries
- CSW: add feature catalogue support parsing
- CRS: support proj.4 CRS definitions (orhygine)
- fix namespaces (jsanchezfr)
- ISO GM03: fix bounding box handling
0.15.0 (2017-09-13)
-------------------
- WFS:
* add doseq to WFS request qyery urlencode
* handle non-existing bounding boxes in feature types
- SOS:
* add support for authentication
- WMTS:
* add support for styles
- ISO:
* add support for gmd:locale
- GM03:
* add support for GM03 ISO metadata profile
- CRS:
* catch invalid CRS codes
- WMS:
* fix time dimension handling in Capabilities
- SWE:
* various bug fixes
- WPS:
* fix WPS DescribeProcess issue on DataType
* fixed bbox lower/upper_corner conversion
* added a test for wps BoundingBoxDataInput
* added BoundingBoxDataInput and fix boundingbox parsing
- Misc:
* fix double ``&&`` in URL requests
* add util.clean_ows_url function to remove basic service parameters from OWS base URLs
0.14.0 (2017-01-12)
-------------------
- WFS: add authentication (@pmauduit)
- WFS: fix parameter names for WFS2
- OWS: implement updateSequence support
- CSW: fix ref bug in CSW-T workflows
- WCS: fix 1.0.0 Capabilities OWS namespace handling
0.13.0 (2016-09-24)
-------------------
- general: Handle servers that give 500 errors better (@davidread)
- WMS: 1.3.0 support @roomthily / @b-cube
- WMS: add WMS request property to cache request URL, add service parameter
- OWS: add ows.ServiceIdentification.versions, fix ref in ows.ServiceIdentification.profiles
0.12.0 (2016-09-12)
-------------------
- OWS: Support OWS Constraints and Parameters
- SOS/WaterML: handle WaterML 2.0 updates and SOS decoder
- Add username and password arguments to WFS class constructors
0.11.0 (2016-04-01)
-------------------
- CSW: fix outputschema setting when raw XML is specified
- ISO:
* parsing anchor for abstract and lineage fields added (madi)
* added support for spatialRepresentationType (pmdias)
* add MD_Keywords class (pmdias)
* fix md.languagecode to come from the codeListValue attribute (pmdias)
- WFS: add get_schema method for DescribeFeatureType parsing (jachym)
- WMS: do not assume parent layers should be queryable if 1..n of their children is
- WMTS: fix parsing when ServiceProvider does not exist
- WPS:
* fix bbox type, parsing bbox output (cehbrecht)
* add support for bbox data and more robust literal data parsing (jachym)
0.10.0 (2015-11-11)
-------------------
- GM03: add support for GM03 metadata
- WPS: add fix for optional Abstract
0.9.2 (2015-09-23)
------------------
- etree: add convenience function to report which etree is used
- WMS: add GetFeatureInfo support (JuergenWeichand)
- WMS: add a children attribute to ContentMetadata to handle WMS nested layers (Jenselme)
- WMTS: add support for restful only WMTS (JuergenWeichand)
- pass headers to requests (ayan-usgs)
0.9.1 (2015-09-03)
------------------
- etree: Fix incorrect lxml ParseError import (daf)
- CRS: make crs hashable (QuLogic)
- WPS:
* statuslocation bugfix (dblodgett-usgs)
* various bugfixes, tests and examples (cehbrecht)
- WFS:
* fix WFS 2.0 stored queries bugfix (JuergenWeichand)
* add docs for WFS 1.1/2.0 (JuergenWeichand)
- ISO: ignored empty gmd:identificationInfo elements (menegon)
0.9.0 (2015-06-12)
------------------
- Python 3 compatibility (numerous contributors!)
- CSW:
* fix Capabilities parsing when ows:ServiceProvider is empty
* fix GetRecordById URL
- WCS: add support for 1.1.1 (ldesousa)
- ISO:
* add support for gmd:MD_ReferenceSystem (kalxas)
* safeguard vars (dblodgett-usgs)
- SOS: add sa namespace, add procedure as optional parameter (ict4eo)
0.8.13 (2015-02-12)
-------------------
- SOS: fix var reference blocker (ocefpaf)
- various Python 3 enhancements
0.8.11 (2014-12-17)
-------------------
- WMTS: add/fix vendor kwarg handling (rhattersley)
- WMS: add ScaleHint support (SiggyF)
- FES: add srsName support for gml:Envelope, add filter to string support
- WFS: add timeout support (selimnairb), add support for startindex
- fix/cleanup tests
0.8.10 (2014-10-13)
-------------------
- CSW: fix bad URL being sent to GetRecords
- SOS: add timeout support (lukecampbell)
- WPS: add logging (dblodgett-usgs)
- WFS: ignore comments when parsing (Samuli Vuorinen)
- tests: add support for logging
- LICENSE: update reference (johanvdw )
0.8.9 (2014-09-24)
-------------------------
- CSW: support ``gmi:MI_Metadata`` as ``gmd:MD_Metadata`` when parsing reuslts (@FuhuXia)
- CSW: add support for basic authentication
- ISO: add support for instantiation of MD_Metadata objects (@kalxas)
- ISO: add support for CI_ResponsibleParty as a responsible role attribute (@milokmet)
- ISO: add title support for SV_ServiceIdentification (@dblodgett-usgs)
- SOS: add 'om' back to namespace list (@ict4eo)
- util: add support for race conditions for WPS (@TobiasKipp)
0.8.8 (2014-07-05)
------------------
- CSW: use URLS as defined in GetCaps for CSW operations (@kwilcox)
- CSW: fix GetRecordById (@kwilcox)
- CSW: use default CSW URL when initialized with skip_caps=True
- WMTS: Allow vendor-specific args in WMTS tile requests (@rhattersley)
- ISO: allow for MD_Metadata to be intialized as empty, supporting export to XML functionality (@kalxas)
- ISO: add support for gmd:RS_Identifier needed by INSPIRE (@kalxas)
- numerous unit test / build fixes and cleanups
0.8.7 (2014-05-02)
------------------
- WPS: add method to write output to disk (@ldesousa)
- CSW: add method to get operations by name
- CSW: responses now maintain order using OrderedDict
- CSW: ensure namespace is declared for GetRecords typeName values in request (@kwilcox)
- SOS: fix error detections (@daf)
- ISO: fix xpath for selecting gmd:thesaurusName (@menegon)
- add timeouts to HTTP functions (@iguest)
- FES: add matchCase to ogc:PropertyIsLike
- logging: add Null handler to not write files randomly (@kwilcox)
- WFS: add GetFeature outputformat support (@kwilcox, @rsignell-usgs)
- ISO: support GML 3.2 extent handling
- numerous unit test / build fixes and cleanups
0.8.3 (2014-01-10)
------------------
- allow CSW URLs to be requested as unicode or string (@rclark)
- support multiple gmd:extent elements (@severo)
- support WMS default time position (@vicb)
- fix SOS GetCapabilities support (@kwilcox)
- support missing CSW nextRecord (@davidread)
- use child layers for WMS duplicates
- numerous unit test fixes and cleanups
0.8.0 (2013-09-11)
------------------
- Support for WaterML 1.0 and 1.1 (thanks @kwilcox and @CowanSM)
- drastically improved CSW getrecords support (owslib.csw.CatalogueServiceWeb.getrecords2, which will eventually replace owslib.csw.CatalogueServiceWeb.getrecords, which is now deprecated) (thanks @kwilcox and @rsignell-usgs input)
- fix owslib.csw.CatalogueServiceWeb to use HTTP GET for GetCapabilities and GetRecordById (thanks @rsignell-usgs for input)
- numerous test fixes
- support owslib.iso.MD_Metadata scanning of multiple extents (thanks @severo)
- add WMS elevation support in Capabilities (thanks @mhermida)
- travis-ci setup (thanks @brianmckenna)
- Support for TMS (thanks @cleder)
- updated build packages (thanks @kalxas)
- numerous bug fixes
0.7 (2013-02-18)
---------------
----------------
- Support for SOS 1.0.0, SOS 2.0.0, SensorML (thanks @kwilcox)
- Support for TMS (thanks @cleder)
......@@ -21,77 +282,81 @@ Changes
- Support for WMTS (thanks @bradh)
- packaging support (thanks @kalxas) for:
- openSUSE
- Debian
* openSUSE
* Debian
- addition of owslib.__version__
- ISO support:
- multiple gmd:identificationInfo elements
- gmd:distributorInfo elements
* multiple gmd:identificationInfo elements
* gmd:distributorInfo elements
- WMS
- read additional Layer attributes (thanks @elemoine)
* read additional Layer attributes (thanks @elemoine)
- numerous bug fixes
0.5 (2012-06-15)
----------------
- Support for the following parsers:
- WPS 1.0.0
- WFS 1.1.0
- CRS handling
- URNs
- URIs
- EPSG:xxxx style
* WPS 1.0.0
* WFS 1.1.0
* CRS handling: URNs, URIs, EPSG:xxxx style
- etree.py looks for lxml.etree first now
- catch WMS service exceptions on GetCapabilities
- CSW exceptions are now Pythonic
0.4 (2011-10-02)
----------------
- Support for the following parsers:
- CSW 2.0.2
- OWS Common 1.0.0, 1.1.0, 2.0.0
- Filter Encoding 1.1.0
- ISO 19115:2003
- FGDC CSDGM
- NASA DIF
- Dublin Core
- WFS 2.0
- WCS 1.1
* CSW 2.0.2
* OWS Common 1.0.0, 1.1.0, 2.0.0
* Filter Encoding 1.1.0
* ISO 19115:2003
* FGDC CSDGM
* NASA DIF
* Dublin Core
* WFS 2.0
* WCS 1.1
- New SCM/bug/mailing list infrastructure
- Sphinx documentation
0.3 (2008-05-08)
----------------
- WCS support.
- Support for basic authorization in WMS requests (#107).
0.2.1 (2007-08-06)
------------------
- Added support for Python 2.5.
- Fixed ticket #105: Don't depend on Content-length in the http headers for
getfeature.
0.2.0 (2007-02-01)
------------------
- Change license to BSD.
- Added service contact metadata.
0.1.0 (2006-10-19)
------------------
- New and improved metadata API.
- Wrappers for GetCapabilities, WMS GetMap, and WFS GetFeature requests.
- Doctests.
0.0.1 (2006-07-30)
------------------
- Brought OWSLib up out of the PCL trunk into its own space.
- Updated the testing frameworm.
- Initial test coverage:
Name Stmts Exec Cover Missing
====== ======= ====== ======= =========
wms 105 68 64% 36, 41-48, 61-63, 114-118, 125-155, 172, 203-205
wfs 74 69 93% 146, 166, 199-201
wmc 111 0 0% 33-220
TOTAL 290 137 47%
====== ======= ====== ======= =========
.. csv-table:: Test Coverage
:header: "Name", "Stmts", "Exec", "Cover", "Missing"
:widths: 5, 5, 5, 5, 20
"wms", 105, 68, 64%, "36, 41-48, 61-63, 114-118, 125-155, 172, 203-205"
"wfs", 74, 69, 93%, "146, 166, 199-201"
"wmc", 111, 0, 0%, "33-220"
"TOTAL", 290, 137, 47%, ""
......@@ -118,7 +118,12 @@ configure your application to use the log messages like so:
>>> import logging
>>> owslib_log = logging.getLogger('owslib')
>>> # Add formatting and handlers as needed
>>> # Add formatting and handlers as needed, for example to log to the console
>>> ch = logging.StreamHandler()
>>> ch.setLevel(logging.DEBUG)
>>> ch.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
>>> # add the handler to the logger
>>> owslib_log.addHandler(ch)
>>> owslib_log.setLevel(logging.DEBUG)
Releasing
......
owslib (0.18.0-3) UNRELEASED; urgency=medium
owslib (0.19.0-1) unstable; urgency=medium
* Team upload.
* New upstream release.
* Bump Standards-Version to 4.4.1, no changes.
-- Bas Couwenberg <sebastic@debian.org> Mon, 30 Sep 2019 19:39:00 +0200
-- Bas Couwenberg <sebastic@debian.org> Fri, 15 Nov 2019 06:58:39 +0100
owslib (0.18.0-2) unstable; urgency=medium
......
......@@ -11,7 +11,6 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
from __future__ import absolute_import
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
......
......@@ -21,7 +21,7 @@ Introduction
OWSLib is a Python package for client programming with `Open Geospatial Consortium`_ (OGC) web service (hence OWS) interface standards, and their related content models.
OWSLib was buried down inside PCL, but has been brought out as a separate project in `r481 <http://trac.gispython.org/lab/changeset/481>`_.
OWSLib was buried down inside PCL (Python Cartography Library), but has been brought out as a separate project.
Features
========
......@@ -29,45 +29,45 @@ Features
Standards Support
-----------------
+-------------------+---------------------+
+-----------------------+-----------------------------+
| Standard | Version(s) |
+===================+=====================+
+=======================+=============================+
| `OGC WMS`_ | 1.1.1 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `OGC WFS`_ | 1.0.0, 1.1.0, 2.0.0, 3.0 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `OGC WCS`_ | 1.0.0, 1.1.0 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `OGC WMC`_ | 1.1.0 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `OGC SOS`_ | 1.0.0, 2.0.0 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `OGC SensorML`_ | 1.0.1 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `OGC CSW`_ | 2.0.2 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `OGC WPS`_ | 1.0.0 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `OGC Filter`_ | 1.1.0 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `OGC OWS Common`_ | 1.0.0, 1.1.0, 2.0 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `OGC OWS Context`_ | 1.0.0 (alpha/under-review) |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `NASA DIF`_ | 9.7 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `FGDC CSDGM`_ | 1998 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `ISO 19139`_ | 2007 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `Dublin Core`_ | 1.1 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `Swiss GM03`_ | 2.3 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `WMTS`_ | 1.0.0 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
| `WaterML`_ | 1.0, 1.1, 2.0 |
+-------------------+---------------------+
+-----------------------+-----------------------------+
Installation
============
......@@ -244,6 +244,14 @@ Download GML using ``typename``, ``bbox`` and ``srsname``.
>>> # OWSLib will switch the axis order from EN to NE automatically if designated by EPSG-Registry
>>> response = wfs11.getfeature(typename='bvv:gmd_ex', bbox=(4500000,5500000,4500500,5500500), srsname='urn:x-ogc:def:crs:EPSG:31468')
Return a FeatureType's schema via ``DescribeFeatureType``. The dictionary returned is
compatible with a `Fiona schema object <https://fiona.readthedocs.io/en/latest/fiona.html#fiona.collection.Collection.schema>`_.
::
>>> wfs11.get_schema('bvv:vg_ex')
>>> {'properties': {'land': 'string', 'modellart': 'string', 'objart': 'string', 'objart_txt': 'string', 'objid': 'string', 'hdu_x': 'short', 'beginn': 'string', 'ende': 'string', 'adm': 'string', 'avg': 'string', 'bez_gem': 'string', 'bez_krs': 'string', 'bez_lan': 'string', 'bez_rbz': 'string', 'sch': 'string'}, 'geometry': '3D MultiPolygon', 'geometry_column': 'geom'}
Download GML using ``typename`` and ``filter``. OWSLib currently only
support filter building for WFS 1.1 (FE.1.1).
......@@ -702,3 +710,6 @@ Credits
.. _`CIA.vc`: http://cia.vc/stats/project/OWSLib
.. _`WaterML`: http://his.cuahsi.org/wofws.html#waterml
.. _`Swiss GM03`: https://www.geocat.admin.ch/en/dokumentation/gm03.html
.. include:: ../../CHANGES.rst
......@@ -8,8 +8,6 @@
# Contact email: tomkralidis@gmail.com
# =============================================================================
from __future__ import absolute_import
from __future__ import print_function
import sys
import getopt
......
......@@ -10,8 +10,6 @@
# simple process to harvest CSW catalogues via Harvest operations
from __future__ import absolute_import
from __future__ import print_function
import sys
from owslib.csw import CatalogueServiceWeb
......
......@@ -10,10 +10,7 @@
# get a list of entries for a given code list dictionary
from __future__ import absolute_import
from __future__ import print_function
import sys
import urllib2
from owslib.etree import etree
from owslib.iso import CodelistCatalogue
......
......@@ -11,8 +11,6 @@
#
# Example to find the equivalent information using OWSLib:
#
from __future__ import absolute_import
from __future__ import print_function
from owslib.wcs import WebCoverageService
wcs=WebCoverageService('http://cida.usgs.gov/thredds/wcs/prism',version='1.0.0')
# Take a look at the contents (coverages) of the wcs.
......
......@@ -2,8 +2,6 @@
This example calls processes on a Emu WPS: https://github.com/bird-house/emu
"""
from __future__ import absolute_import
from __future__ import print_function
from owslib.wps import WebProcessingService, ComplexDataInput, monitorExecution
verbose = False
......
# Example script that performs a set of (small) live requests versus the live CEDA WPS service
from __future__ import absolute_import
from __future__ import print_function
from owslib.wps import WebProcessingService, WPSExecution, WFSFeatureCollection, WFSQuery, GMLMultiPolygonFeatureCollection, monitorExecution, ComplexData, printInputOutput
from owslib.util import dump
......
......@@ -6,8 +6,6 @@
#
# =============================================================================
from __future__ import absolute_import
from __future__ import print_function
import sys
import getopt
import os
......
# Example script that performs a set of (small) live requests versus the live PML WPS service
from __future__ import absolute_import
from __future__ import print_function
from owslib.wps import WebProcessingService, monitorExecution
# instantiate WPS client
......
# Example script that performs a set of (small) live requests versus the live PML WPS service
from __future__ import absolute_import
from __future__ import print_function
from owslib.wps import WebProcessingService, monitorExecution
# instantiate WPS client
......
# Example script that performs a set of (small) live requests versus the live USGS WPS service
from __future__ import absolute_import
from __future__ import print_function
from owslib.wps import WebProcessingService, WPSExecution, WFSFeatureCollection, WFSQuery, GMLMultiPolygonFeatureCollection, monitorExecution, printInputOutput
from owslib.util import dump
......
from __future__ import (absolute_import, division, print_function)
__version__ = '0.18.0'
__version__ = '0.19.0'
from __future__ import (absolute_import, division, print_function)
......@@ -9,25 +9,23 @@
# Contact email: d.lowe@rl.ac.uk
# =============================================================================
from __future__ import (absolute_import, division, print_function)
from owslib.coverage.wcsBase import WCSBase, WCSCapabilitiesReader, ServiceException
try:
from urllib import urlencode
except ImportError:
from urllib.parse import urlencode
from owslib.util import openURL, testXMLValue
from owslib.etree import etree
from owslib.crs import Crs
import os, errno
import os
import errno
import logging
from owslib.util import log
# function to save writing out WCS namespace in full each time
def ns(tag):
return '{http://www.opengis.net/wcs}' + tag
class WebCoverageService_1_0_0(WCSBase):
"""Abstraction for OGC Web Coverage Service (WCS), version 1.0.0
Implements IWebCoverageService.
......@@ -35,7 +33,7 @@ class WebCoverageService_1_0_0(WCSBase):
def __getitem__(self, name):
''' check contents dictionary to allow dict like access to service layers'''
if name in self.__getattribute__('contents').keys():
if name in list(self.__getattribute__('contents').keys()):
return self.__getattribute__('contents')[name]
else:
raise KeyError("No content named %s" % name)
......@@ -87,8 +85,7 @@ class WebCoverageService_1_0_0(WCSBase):
self.contents[cm.id] = cm
# exceptions
self.exceptions = [f.text for f \
in self._capabilities.findall('Capability/Exception/Format')]
self.exceptions = [f.text for f in self._capabilities.findall('Capability/Exception/Format')]
def items(self):
'''supports dict-like items() access'''
......@@ -105,22 +102,27 @@ class WebCoverageService_1_0_0(WCSBase):
sval = value
return sval
def getCoverage(self, identifier=None, bbox=None, time=None, format = None, crs=None, width=None, height=None, resx=None, resy=None, resz=None,parameter=None,method='Get',**kwargs):
def getCoverage(self, identifier=None, bbox=None, time=None, format=None, crs=None, width=None, height=None,
resx=None, resy=None, resz=None, parameter=None, method='Get', **kwargs):
"""Request and return a coverage from the WCS as a file-like object
note: additional **kwargs helps with multi-version implementation
core keyword arguments should be supported cross version
example:
cvg=wcs.getCoverage(identifier=['TuMYrRQ4'], timeSequence=['2792-06-01T00:00:00.0'], bbox=(-112,36,-106,41),format='cf-netcdf')
cvg=wcs.getCoverage(identifier=['TuMYrRQ4'], timeSequence=['2792-06-01T00:00:00.0'], bbox=(-112,36,-106,41),
format='cf-netcdf')
is equivalent to:
http://myhost/mywcs?SERVICE=WCS&REQUEST=GetCoverage&IDENTIFIER=TuMYrRQ4&VERSION=1.1.0&BOUNDINGBOX=-180,-90,180,90&TIME=2792-06-01T00:00:00.0&FORMAT=cf-netcdf
"""
if log.isEnabledFor(logging.DEBUG):
log.debug('WCS 1.0.0 DEBUG: Parameters passed to GetCoverage: identifier=%s, bbox=%s, time=%s, format=%s, crs=%s, width=%s, height=%s, resx=%s, resy=%s, resz=%s, parameter=%s, method=%s, other_arguments=%s'%(identifier, bbox, time, format, crs, width, height, resx, resy, resz, parameter, method, str(kwargs)))
msg = 'WCS 1.0.0 DEBUG: Parameters passed to GetCoverage: identifier={}, bbox={}, time={}, format={}, crs={}, width={}, height={}, resx={}, resy={}, resz={}, parameter={}, method={}, other_arguments={}' # noqa
log.debug(msg.format(
identifier, bbox, time, format, crs, width, height, resx, resy, resz, parameter, method, str(kwargs)))
try:
base_url = next((m.get('url') for m in self.getOperationByName('GetCoverage').methods if m.get('type').lower() == method.lower()))
base_url = next((m.get('url') for m in self.getOperationByName('GetCoverage').methods
if m.get('type').lower() == method.lower()))
except StopIteration:
base_url = self.url
......@@ -181,7 +183,7 @@ class OperationMetadata(object):
"""."""
self.name = elem.tag.split('}')[1]
#self.formatOptions = [f.text for f in elem.findall('{http://www.opengis.net/wcs/1.1/ows}Parameter/{http://www.opengis.net/wcs/1.1/ows}AllowedValues/{http://www.opengis.net/wcs/1.1/ows}Value')]
# self.formatOptions = [f.text for f in elem.findall('{http://www.opengis.net/wcs/1.1/ows}Parameter/{http://www.opengis.net/wcs/1.1/ows}AllowedValues/{http://www.opengis.net/wcs/1.1/ows}Value')] # noqa
self.methods = []
for resource in elem.findall(ns('DCPType/') + ns('HTTP/') + ns('Get/') + ns('OnlineResource')):
url = resource.attrib['{http://www.w3.org/1999/xlink}href']
......@@ -205,6 +207,7 @@ class ServiceIdentification(object):
self.fees = elem.find(ns('fees')).text
self.accessConstraints = elem.find(ns('accessConstraints')).text
class ServiceProvider(object):
""" Abstraction for WCS ResponsibleParty
Implements IServiceProvider"""
......@@ -220,6 +223,7 @@ class ServiceProvider(object):
self.url = self.name # there is no definitive place for url WCS, repeat organisationName
self.contact = ContactMetadata(elem)
class ContactMetadata(object):
''' implements IContactMetadata'''
def __init__(self, elem):
......@@ -256,6 +260,7 @@ class ContactMetadata(object):
except AttributeError:
self.email = None
class ContentMetadata(object):
"""
Implements IContentMetadata
......@@ -291,16 +296,19 @@ class ContentMetadata(object):
def _getGrid(self):
if not hasattr(self, 'descCov'):
self.descCov = self._service.getDescribeCoverage(self.id)
gridelem= self.descCov.find(ns('CoverageOffering/')+ns('domainSet/')+ns('spatialDomain/')+'{http://www.opengis.net/gml}RectifiedGrid')
gridelem = self.descCov.find(
ns('CoverageOffering/') + ns('domainSet/') + ns('spatialDomain/') + '{http://www.opengis.net/gml}RectifiedGrid') # noqa
if gridelem is not None:
grid = RectifiedGrid(gridelem)
else:
gridelem=self.descCov.find(ns('CoverageOffering/')+ns('domainSet/')+ns('spatialDomain/')+'{http://www.opengis.net/gml}Grid')
gridelem = self.descCov.find(
ns('CoverageOffering/') + ns('domainSet/') + ns('spatialDomain/') + '{http://www.opengis.net/gml}Grid') # noqa
grid = Grid(gridelem)
return grid
grid = property(_getGrid, None)
#timelimits are the start/end times, timepositions are all timepoints. WCS servers can declare one or both or neither of these.
# timelimits are the start/end times, timepositions are all timepoints.
# WCS servers can declare one or both or neither of these.
def _getTimeLimits(self):
timepoints, timelimits = [], []
b = self._elem.find(ns('lonLatEnvelope'))
......@@ -310,7 +318,8 @@ class ContentMetadata(object):
# have to make a describeCoverage request...
if not hasattr(self, 'descCov'):
self.descCov = self._service.getDescribeCoverage(self.id)
for pos in self.descCov.findall(ns('CoverageOffering/')+ns('domainSet/')+ns('temporalDomain/')+'{http://www.opengis.net/gml}timePosition'):
for pos in self.descCov.findall(
ns('CoverageOffering/') + ns('domainSet/') + ns('temporalDomain/') + '{http://www.opengis.net/gml}timePosition'): # noqa
timepoints.append(pos)
if timepoints:
timelimits = [timepoints[0].text, timepoints[1].text]
......@@ -321,22 +330,22 @@ class ContentMetadata(object):
timepositions = []
if not hasattr(self, 'descCov'):
self.descCov = self._service.getDescribeCoverage(self.id)
for pos in self.descCov.findall(ns('CoverageOffering/')+ns('domainSet/')+ns('temporalDomain/')+'{http://www.opengis.net/gml}timePosition'):
for pos in self.descCov.findall(
ns('CoverageOffering/') + ns('domainSet/') + ns('temporalDomain/') + '{http://www.opengis.net/gml}timePosition'): # noqa
timepositions.append(pos.text)
return timepositions
timepositions = property(_getTimePositions, None)
def _getOtherBoundingBoxes(self):
''' incomplete, should return other bounding boxes not in WGS84
#TODO: find any other bounding boxes. Need to check for gml:EnvelopeWithTimePeriod.'''
bboxes = []
if not hasattr(self, 'descCov'):
self.descCov = self._service.getDescribeCoverage(self.id)
for envelope in self.descCov.findall(ns('CoverageOffering/')+ns('domainSet/')+ns('spatialDomain/')+'{http://www.opengis.net/gml}Envelope'):
for envelope in self.descCov.findall(
ns('CoverageOffering/') + ns('domainSet/') + ns('spatialDomain/') + '{http://www.opengis.net/gml}Envelope'): # noqa
bbox = {}
bbox['nativeSrs'] = envelope.attrib['srsName']
gmlpositions = envelope.findall('{http://www.opengis.net/gml}pos')
......@@ -354,23 +363,26 @@ class ContentMetadata(object):
def _getSupportedCRSProperty(self):
# gets supported crs info
crss = []
for elem in self._service.getDescribeCoverage(self.id).findall(ns('CoverageOffering/')+ns('supportedCRSs/')+ns('responseCRSs')):
for elem in self._service.getDescribeCoverage(self.id).findall(
ns('CoverageOffering/') + ns('supportedCRSs/') + ns('responseCRSs')):
for crs in elem.text.split(' '):
crss.append(Crs(crs))
for elem in self._service.getDescribeCoverage(self.id).findall(ns('CoverageOffering/')+ns('supportedCRSs/')+ns('requestResponseCRSs')):
for elem in self._service.getDescribeCoverage(self.id).findall(
ns('CoverageOffering/') + ns('supportedCRSs/') + ns('requestResponseCRSs')):
for crs in elem.text.split(' '):
crss.append(Crs(crs))
for elem in self._service.getDescribeCoverage(self.id).findall(ns('CoverageOffering/')+ns('supportedCRSs/')+ns('nativeCRSs')):
for elem in self._service.getDescribeCoverage(self.id).findall(
ns('CoverageOffering/') + ns('supportedCRSs/') + ns('nativeCRSs')):
for crs in elem.text.split(' '):
crss.append(Crs(crs))
return crss
supportedCRS = property(_getSupportedCRSProperty, None)
def _getSupportedFormatsProperty(self):
# gets supported formats info
frmts = []
for elem in self._service.getDescribeCoverage(self.id).findall(ns('CoverageOffering/')+ns('supportedFormats/')+ns('formats')):
for elem in self._service.getDescribeCoverage(self.id).findall(
ns('CoverageOffering/') + ns('supportedFormats/') + ns('formats')):
frmts.append(elem.text)
return frmts
supportedFormats = property(_getSupportedFormatsProperty, None)
......@@ -378,16 +390,18 @@ class ContentMetadata(object):
def _getAxisDescriptionsProperty(self):
# gets any axis descriptions contained in the rangeset (requires a DescribeCoverage call to server).
axisDescs = []
for elem in self._service.getDescribeCoverage(self.id).findall(ns('CoverageOffering/')+ns('rangeSet/')+ns('RangeSet/')+ns('axisDescription/')+ns('AxisDescription')):
for elem in self._service.getDescribeCoverage(self.id).findall(
ns('CoverageOffering/') + ns('rangeSet/') + ns('RangeSet/') + ns('axisDescription/') + ns('AxisDescription')): # noqa
axisDescs.append(AxisDescription(elem)) # create a 'AxisDescription' object.
return axisDescs
axisDescriptions = property(_getAxisDescriptionsProperty, None)
# Adding classes to represent gml:grid and gml:rectifiedgrid. One of these is used for the cvg.grid property
# (where cvg is a member of the contents dictionary)
#There is no simple way to convert the offset values in a rectifiedgrid grid to real values without CRS understanding, therefore this is beyond the current scope of owslib, so the representation here is purely to provide access to the information in the GML.
# There is no simple way to convert the offset values in a rectifiedgrid grid to real values without CRS understanding,
# therefore this is beyond the current scope of owslib, so the representation here is purely to provide access
# to the information in the GML.
class Grid(object):
''' Simple grid class to provide axis and value information for a gml grid '''
......@@ -398,8 +412,10 @@ class Grid(object):
self.highlimits = []
if grid is not None:
self.dimension = int(grid.get('dimension'))
self.lowlimits= grid.find('{http://www.opengis.net/gml}limits/{http://www.opengis.net/gml}GridEnvelope/{http://www.opengis.net/gml}low').text.split(' ')
self.highlimits = grid.find('{http://www.opengis.net/gml}limits/{http://www.opengis.net/gml}GridEnvelope/{http://www.opengis.net/gml}high').text.split(' ')
self.lowlimits = grid.find(
'{http://www.opengis.net/gml}limits/{http://www.opengis.net/gml}GridEnvelope/{http://www.opengis.net/gml}low').text.split(' ') # noqa
self.highlimits = grid.find(
'{http://www.opengis.net/gml}limits/{http://www.opengis.net/gml}GridEnvelope/{http://www.opengis.net/gml}high').text.split(' ') # noqa
for axis in grid.findall('{http://www.opengis.net/gml}axisName'):
self.axislabels.append(axis.text)
......@@ -408,11 +424,13 @@ class RectifiedGrid(Grid):
''' RectifiedGrid class, extends Grid with additional offset vector information '''
def __init__(self, rectifiedgrid):
super(RectifiedGrid, self).__init__(rectifiedgrid)
self.origin=rectifiedgrid.find('{http://www.opengis.net/gml}origin/{http://www.opengis.net/gml}pos').text.split()
self.origin = rectifiedgrid.find(
'{http://www.opengis.net/gml}origin/{http://www.opengis.net/gml}pos').text.split()
self.offsetvectors = []
for offset in rectifiedgrid.findall('{http://www.opengis.net/gml}offsetVector'):
self.offsetvectors.append(offset.text.split())
class AxisDescription(object):
''' Class to represent the AxisDescription element optionally found as part of the RangeSet and used to
define ordinates of additional dimensions such as wavelength bands or pressure levels'''
......