wcs


Namewcs JSON
Version 0.2.3 PyPI version JSON
download
home_pageNone
SummaryPython client library for WCS (OGC Web Coverage Service) backends.
upload_time2025-01-22 10:52:49
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseNone
keywords wcs wcps rasdaman ogc gis web coverage service
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Overview

The [OGC Web Coverage Service (WCS) standard](https://www.ogc.org/standards/wcs)
defines support for modeling and retrieval of geospatial data as coverages 
(e.g. sensor, image, or statistics data).

This Python library allows to extract information about WCS coverages from a
given WCS endpoint.

Note that downloading raster data is not supported. This can be done with
the [WCPS Python Client](https://rasdaman.github.io/wcps-python-client/).

# Installation

    pip install wcs

# Examples

## List Coverages

The example below illustrates how to get a list of 
[BasicCoverage](https://rasdaman.github.io/wcs-python-client/autoapi/wcs/model/index.html#wcs.model.BasicCoverage)
objects for all coverages (datacubes) on the server, and extract various details
for a particular coverage.

First we need to create a
[WebCoverageService](https://rasdaman.github.io/wcs-python-client/autoapi/wcs/service/index.html#wcs.service.WebCoverageService)
object. Optionally, a username and a password may be specified, if the endpoint requires them.

```python
from wcs.service import WebCoverageService

wcs_endpoint = "https://fairicube.rasdaman.com/rasdaman/ows"
service = WebCoverageService(wcs_endpoint)

# or with credentials:
# service = WebCoverageService(wcs_endpoint,
#                              username=..., password=...)
```

With the `service` object we can get a map of all coverages
(coverage name -> [BasicCoverage](https://rasdaman.github.io/wcs-python-client/autoapi/wcs/model/index.html#wcs.model.BasicCoverage)), 
with basic information such as a WGS 84 bounding box and a native bounding box:

```python
coverages = service.list_coverages()
```

Let's print information of a single coverage with name `dominant_leaf_type_20m`:

```python
cov = coverages['dominant_leaf_type_20m']

print(cov)
```
```yaml
dominant_leaf_type_20m:
  subtype: ReferenceableGridCoverage
  native CRS: OGC:AnsiDate+EPSG:3035
  geo bbox:
    time:
      min: "2012-01-01"
      max: "2015-01-01"
      crs: OGC:AnsiDate
    Y:
      min: 900000
      max: 5500000
      crs: EPSG:3035
    X:
      min: 900000
      max: 7400000
      crs: EPSG:3035
  lon/lat bbox:
    Lon:
      min: -56.50514190170437
      max: 72.9061049341568
      crs: EPSG:4326
    Lat:
      min: 24.28417068794856
      max: 72.66326966834436
      crs: EPSG:4326
  size in bytes: 113000000001
  additional params:
    title: Dominant Leaf Type (2012-2015)
    sizeInBytesWithPyramidLevels: "113000000001"
```

Examples for extracting individual details of the coverage:

```python
# coverage subtype

print(cov.subtype)

# ReferenceableGridCoverage

# coverage bounding box, containing the CRS and axes

bbox = cov.bbox

# full coverage crs identifier

print(bbox.crs)

# https://www.opengis.net/def/crs-compound?
# 1=https://www.opengis.net/def/crs/OGC/0/AnsiDate?axis-label="time"&
# 2=https://www.opengis.net/def/crs/EPSG/0/3035

# coverage crs identifier in shorthand notation

from wcs.model import Crs

print(Crs.to_short_notation(bbox.crs))

# OGC:AnsiDate+EPSG:3035

# get information for the first axis; as it is a temporal axis,
# the lower_bound and upper_bound are datetime.datetime objects.

axis = bbox.time

# note that these are all equivalent:
# axis = bbox['time']
# axis = bbox[0]

name = axis.name
lower_bound = axis.low
upper_bound = axis.high
print(f'{name}({lower_bound} - {upper_bound})')
# time(2012-01-01 00:00:00+00:00 - 2015-01-01 00:00:00+00:00)

# get size in bytes if available

if cov.size_bytes is not None:
    print(cov.size_bytes)
    # 113000000001
```

## Full Coverage Information

The previous example gets basic information about the coverage
through what is published in the WCS *GetCapabilities* response.

More detailed information can be retrieved with the 
`service.list_full_info` method, which parses the corresponding *DescribeCoverage* document and returns a
[FullCoverage](https://rasdaman.github.io/wcs-python-client/autoapi/wcs/model/index.html#wcs.model.FullCoverage)
object:

```python
cov = service.list_full_info('dominant_leaf_type_20m')

# print all information

print(cov)
```
```yaml
dominant_leaf_type_20m:
  native CRS: OGC:AnsiDate+EPSG:3035
  geo bbox:
    time:
      min: 2012-01-01
      max: 2015-01-01
      crs: OGC:AnsiDate
      uom: d
      type: irregular
      coefficients:
        - 2012-01-01
        - 2015-01-01
    Y:
      min: 900000
      max: 5500000
      crs: EPSG:3035
      uom: metre
      resolution: -20
      type: regular
    X:
      min: 900000
      max: 7400000
      crs: EPSG:3035
      uom: metre
      resolution: 20
      type: regular
  grid bbox:
    i:
      min: 0
      max: 1
      resolution: 1
      type: regular
    j:
      min: -125000
      max: 104999
      resolution: 1
      type: regular
    k:
      min: 0
      max: 324999
      resolution: 1
      type: regular
  range type fields:
    dlt:
      type: Category
      label: dominant leaf type map of Europe
      description: >
        raster coding (thematic pixel values): 
        0: all non-tree covered areas; 
        1: broadleaved trees; 
        2: coniferous trees; 
        254: unclassifiable (no satellite image available, or clouds, shadows, or snow); 
        255: outside area
      definition: https://land.copernicus.eu/en/technical-library/hrl-forest-2012-2015/@@download/file
      nil values: 250
  metadata:
    covMetadata:
      axes:
        time:
          areasOfValidity:
            area:
              - 
                "@start": 2011-01-01T00:00:00.000Z
                "@end": 2013-12-31T23:59:59.999Z
              - 
                "@start": 2014-01-01T00:00:00.000Z
                "@end": 2016-12-31T23:59:59.999Z
    rasdamanCoverageMetadata:
      catalog:
        title: Dominant Leaf Type (2012-2015)
        thumbnail: https://fairicube.rasdaman.com/rasdaman/ows/coverage/thumbnail?COVERAGEID=dominant_leaf_type_20m
        description: Provides at pan-European level in the spatial resolution of 20 m information on the dominant leaf type (broadleaved or coniferous).
        provenance:
          "@sourceUrl": https://land.copernicus.eu/en/products/high-resolution-layer-dominant-leaf-type
          "@providerName": Copernicus
          "@termsUrl": https://land.copernicus.eu/en/data-policy
        ourTerms: https://fairicube.rasdaman.com/#terms
    fairicubeMetadata:
      "@role": https://codelists.fairicube.eu/metadata/MetadataCatalogLink
      "@title": Metadata in the FAIRiCUBE Catalog
      "@href": https://stacapi.eoxhub.fairicube.eu/collections/index/items/dominant_leaf_type_20m
```

In addition to the geo `bbox` in native CRS, the 
`FullCoverage` object also has a `grid_bbox` attribute, which contains 
the integer grid axis bounds of the coverage. This is the same 
type of 
[BoundingBox](https://rasdaman.github.io/wcs-python-client/autoapi/wcs/model/index.html#wcs.model.BoundingBox)
object, except its `crs` attribute is `None`.

```python
print(cov.grid_bbox)
```

The `range_type` attribute indicates the structure of the cell values
of the coverage. It contains a `fields` attribute, which is
a list of
[Field](https://rasdaman.github.io/wcs-python-client/autoapi/wcs/model/index.html#wcs.model.Field)
objects corresponding to the bands of the 
coverage. Check the documentation of
[RangeType](https://rasdaman.github.io/wcs-python-client/autoapi/wcs/model/index.html#wcs.model.RangeType)
for full details.

```python
range_type = cov.range_type
all_fields = range_type.fields
dlt = range_type.dlt

# note that these are all equivalent:
# field = range_type['dlt']
# field = range_type[0]

# get all properties of the field

label = dlt.label
description = dlt.description
definition = dlt.definition
nil_values = dlt.nil_values
if dlt.is_quantity:
    uom = dlt.uom
else:
    codespace = dlt.codespace
```

Finally, any coverage metadata is available from the `metadata` attribute,
which is a nested dict mirroring the XML structure in the *DescribeCoverage* document.
E.g. to get the link to the FAIRiCUBE catalog entry for this coverage:

```python
catalog_link = cov.metadata['fairicubeMetadata']['@href']
```

# Contributing

The directory structure is as follows:

- `wcs` - the main library code
- `tests` - testing code
- `docs` - documentation in reStructuredText format

The `./pylint.sh` script should be executed before committing code changes.

## Tests

To run the tests:

```
# install dependencies
pip install wcs[tests]

pytest
```

## Documentation

To build the documentation:

```
# install dependencies
pip install wcs[docs]

cd docs
make html
```

The built documentation can be found in the `docs/_build/html/` subdir.


# Acknowledgments

Created in project [EU FAIRiCUBE](https://fairicube.nilu.no/), with funding from the 
Horizon Europe programme under grant agreement No 101059238.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "wcs",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "wcs, wcps, rasdaman, ogc, gis, Web Coverage Service",
    "author": null,
    "author_email": "Dimitar Misev <misev@rasdaman.com>",
    "download_url": "https://files.pythonhosted.org/packages/3f/89/f95c8bb125196f7f2271922e5c34254852b4546890e7da301fa7c613f074/wcs-0.2.3.tar.gz",
    "platform": null,
    "description": "# Overview\n\nThe [OGC Web Coverage Service (WCS) standard](https://www.ogc.org/standards/wcs)\ndefines support for modeling and retrieval of geospatial data as coverages \n(e.g. sensor, image, or statistics data).\n\nThis Python library allows to extract information about WCS coverages from a\ngiven WCS endpoint.\n\nNote that downloading raster data is not supported. This can be done with\nthe [WCPS Python Client](https://rasdaman.github.io/wcps-python-client/).\n\n# Installation\n\n    pip install wcs\n\n# Examples\n\n## List Coverages\n\nThe example below illustrates how to get a list of \n[BasicCoverage](https://rasdaman.github.io/wcs-python-client/autoapi/wcs/model/index.html#wcs.model.BasicCoverage)\nobjects for all coverages (datacubes) on the server, and extract various details\nfor a particular coverage.\n\nFirst we need to create a\n[WebCoverageService](https://rasdaman.github.io/wcs-python-client/autoapi/wcs/service/index.html#wcs.service.WebCoverageService)\nobject. Optionally, a username and a password may be specified, if the endpoint requires them.\n\n```python\nfrom wcs.service import WebCoverageService\n\nwcs_endpoint = \"https://fairicube.rasdaman.com/rasdaman/ows\"\nservice = WebCoverageService(wcs_endpoint)\n\n# or with credentials:\n# service = WebCoverageService(wcs_endpoint,\n#                              username=..., password=...)\n```\n\nWith the `service` object we can get a map of all coverages\n(coverage name -> [BasicCoverage](https://rasdaman.github.io/wcs-python-client/autoapi/wcs/model/index.html#wcs.model.BasicCoverage)), \nwith basic information such as a WGS 84 bounding box and a native bounding box:\n\n```python\ncoverages = service.list_coverages()\n```\n\nLet's print information of a single coverage with name `dominant_leaf_type_20m`:\n\n```python\ncov = coverages['dominant_leaf_type_20m']\n\nprint(cov)\n```\n```yaml\ndominant_leaf_type_20m:\n  subtype: ReferenceableGridCoverage\n  native CRS: OGC:AnsiDate+EPSG:3035\n  geo bbox:\n    time:\n      min: \"2012-01-01\"\n      max: \"2015-01-01\"\n      crs: OGC:AnsiDate\n    Y:\n      min: 900000\n      max: 5500000\n      crs: EPSG:3035\n    X:\n      min: 900000\n      max: 7400000\n      crs: EPSG:3035\n  lon/lat bbox:\n    Lon:\n      min: -56.50514190170437\n      max: 72.9061049341568\n      crs: EPSG:4326\n    Lat:\n      min: 24.28417068794856\n      max: 72.66326966834436\n      crs: EPSG:4326\n  size in bytes: 113000000001\n  additional params:\n    title: Dominant Leaf Type (2012-2015)\n    sizeInBytesWithPyramidLevels: \"113000000001\"\n```\n\nExamples for extracting individual details of the coverage:\n\n```python\n# coverage subtype\n\nprint(cov.subtype)\n\n# ReferenceableGridCoverage\n\n# coverage bounding box, containing the CRS and axes\n\nbbox = cov.bbox\n\n# full coverage crs identifier\n\nprint(bbox.crs)\n\n# https://www.opengis.net/def/crs-compound?\n# 1=https://www.opengis.net/def/crs/OGC/0/AnsiDate?axis-label=\"time\"&\n# 2=https://www.opengis.net/def/crs/EPSG/0/3035\n\n# coverage crs identifier in shorthand notation\n\nfrom wcs.model import Crs\n\nprint(Crs.to_short_notation(bbox.crs))\n\n# OGC:AnsiDate+EPSG:3035\n\n# get information for the first axis; as it is a temporal axis,\n# the lower_bound and upper_bound are datetime.datetime objects.\n\naxis = bbox.time\n\n# note that these are all equivalent:\n# axis = bbox['time']\n# axis = bbox[0]\n\nname = axis.name\nlower_bound = axis.low\nupper_bound = axis.high\nprint(f'{name}({lower_bound} - {upper_bound})')\n# time(2012-01-01 00:00:00+00:00 - 2015-01-01 00:00:00+00:00)\n\n# get size in bytes if available\n\nif cov.size_bytes is not None:\n    print(cov.size_bytes)\n    # 113000000001\n```\n\n## Full Coverage Information\n\nThe previous example gets basic information about the coverage\nthrough what is published in the WCS *GetCapabilities* response.\n\nMore detailed information can be retrieved with the \n`service.list_full_info` method, which parses the corresponding *DescribeCoverage* document and returns a\n[FullCoverage](https://rasdaman.github.io/wcs-python-client/autoapi/wcs/model/index.html#wcs.model.FullCoverage)\nobject:\n\n```python\ncov = service.list_full_info('dominant_leaf_type_20m')\n\n# print all information\n\nprint(cov)\n```\n```yaml\ndominant_leaf_type_20m:\n  native CRS: OGC:AnsiDate+EPSG:3035\n  geo bbox:\n    time:\n      min: 2012-01-01\n      max: 2015-01-01\n      crs: OGC:AnsiDate\n      uom: d\n      type: irregular\n      coefficients:\n        - 2012-01-01\n        - 2015-01-01\n    Y:\n      min: 900000\n      max: 5500000\n      crs: EPSG:3035\n      uom: metre\n      resolution: -20\n      type: regular\n    X:\n      min: 900000\n      max: 7400000\n      crs: EPSG:3035\n      uom: metre\n      resolution: 20\n      type: regular\n  grid bbox:\n    i:\n      min: 0\n      max: 1\n      resolution: 1\n      type: regular\n    j:\n      min: -125000\n      max: 104999\n      resolution: 1\n      type: regular\n    k:\n      min: 0\n      max: 324999\n      resolution: 1\n      type: regular\n  range type fields:\n    dlt:\n      type: Category\n      label: dominant leaf type map of Europe\n      description: >\n        raster coding (thematic pixel values): \n        0: all non-tree covered areas; \n        1: broadleaved trees; \n        2: coniferous trees; \n        254: unclassifiable (no satellite image available, or clouds, shadows, or snow); \n        255: outside area\n      definition: https://land.copernicus.eu/en/technical-library/hrl-forest-2012-2015/@@download/file\n      nil values: 250\n  metadata:\n    covMetadata:\n      axes:\n        time:\n          areasOfValidity:\n            area:\n              - \n                \"@start\": 2011-01-01T00:00:00.000Z\n                \"@end\": 2013-12-31T23:59:59.999Z\n              - \n                \"@start\": 2014-01-01T00:00:00.000Z\n                \"@end\": 2016-12-31T23:59:59.999Z\n    rasdamanCoverageMetadata:\n      catalog:\n        title: Dominant Leaf Type (2012-2015)\n        thumbnail: https://fairicube.rasdaman.com/rasdaman/ows/coverage/thumbnail?COVERAGEID=dominant_leaf_type_20m\n        description: Provides at pan-European level in the spatial resolution of 20 m information on the dominant leaf type (broadleaved or coniferous).\n        provenance:\n          \"@sourceUrl\": https://land.copernicus.eu/en/products/high-resolution-layer-dominant-leaf-type\n          \"@providerName\": Copernicus\n          \"@termsUrl\": https://land.copernicus.eu/en/data-policy\n        ourTerms: https://fairicube.rasdaman.com/#terms\n    fairicubeMetadata:\n      \"@role\": https://codelists.fairicube.eu/metadata/MetadataCatalogLink\n      \"@title\": Metadata in the FAIRiCUBE Catalog\n      \"@href\": https://stacapi.eoxhub.fairicube.eu/collections/index/items/dominant_leaf_type_20m\n```\n\nIn addition to the geo `bbox` in native CRS, the \n`FullCoverage` object also has a `grid_bbox` attribute, which contains \nthe integer grid axis bounds of the coverage. This is the same \ntype of \n[BoundingBox](https://rasdaman.github.io/wcs-python-client/autoapi/wcs/model/index.html#wcs.model.BoundingBox)\nobject, except its `crs` attribute is `None`.\n\n```python\nprint(cov.grid_bbox)\n```\n\nThe `range_type` attribute indicates the structure of the cell values\nof the coverage. It contains a `fields` attribute, which is\na list of\n[Field](https://rasdaman.github.io/wcs-python-client/autoapi/wcs/model/index.html#wcs.model.Field)\nobjects corresponding to the bands of the \ncoverage. Check the documentation of\n[RangeType](https://rasdaman.github.io/wcs-python-client/autoapi/wcs/model/index.html#wcs.model.RangeType)\nfor full details.\n\n```python\nrange_type = cov.range_type\nall_fields = range_type.fields\ndlt = range_type.dlt\n\n# note that these are all equivalent:\n# field = range_type['dlt']\n# field = range_type[0]\n\n# get all properties of the field\n\nlabel = dlt.label\ndescription = dlt.description\ndefinition = dlt.definition\nnil_values = dlt.nil_values\nif dlt.is_quantity:\n    uom = dlt.uom\nelse:\n    codespace = dlt.codespace\n```\n\nFinally, any coverage metadata is available from the `metadata` attribute,\nwhich is a nested dict mirroring the XML structure in the *DescribeCoverage* document.\nE.g. to get the link to the FAIRiCUBE catalog entry for this coverage:\n\n```python\ncatalog_link = cov.metadata['fairicubeMetadata']['@href']\n```\n\n# Contributing\n\nThe directory structure is as follows:\n\n- `wcs` - the main library code\n- `tests` - testing code\n- `docs` - documentation in reStructuredText format\n\nThe `./pylint.sh` script should be executed before committing code changes.\n\n## Tests\n\nTo run the tests:\n\n```\n# install dependencies\npip install wcs[tests]\n\npytest\n```\n\n## Documentation\n\nTo build the documentation:\n\n```\n# install dependencies\npip install wcs[docs]\n\ncd docs\nmake html\n```\n\nThe built documentation can be found in the `docs/_build/html/` subdir.\n\n\n# Acknowledgments\n\nCreated in project [EU FAIRiCUBE](https://fairicube.nilu.no/), with funding from the \nHorizon Europe programme under grant agreement No 101059238.\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Python client library for WCS (OGC Web Coverage Service) backends.",
    "version": "0.2.3",
    "project_urls": {
        "Documentation": "https://rasdaman.github.io/wcs-python-client/",
        "Issues": "https://github.com/rasdaman/wcs-python-client/issues",
        "Source": "https://github.com/rasdaman/wcs-python-client"
    },
    "split_keywords": [
        "wcs",
        " wcps",
        " rasdaman",
        " ogc",
        " gis",
        " web coverage service"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "58dcd89daf402eaf05e188ec7cf0ed23b8e5404afab212ac58ff3c924b71e0b0",
                "md5": "f1a23050bba9a268f73973eb8a69088d",
                "sha256": "0678333897e8a45cb96aad3ba8b63f930ad7b16dbdbcb09c24b965d6ec6defa4"
            },
            "downloads": -1,
            "filename": "wcs-0.2.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "f1a23050bba9a268f73973eb8a69088d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 23813,
            "upload_time": "2025-01-22T10:52:47",
            "upload_time_iso_8601": "2025-01-22T10:52:47.063880Z",
            "url": "https://files.pythonhosted.org/packages/58/dc/d89daf402eaf05e188ec7cf0ed23b8e5404afab212ac58ff3c924b71e0b0/wcs-0.2.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3f89f95c8bb125196f7f2271922e5c34254852b4546890e7da301fa7c613f074",
                "md5": "1415a7f1b0286ba75ab2f270188de818",
                "sha256": "c31671971086a9236d3b42a8d2f3ace25365fadae1a8f5380999b7098c9e315c"
            },
            "downloads": -1,
            "filename": "wcs-0.2.3.tar.gz",
            "has_sig": false,
            "md5_digest": "1415a7f1b0286ba75ab2f270188de818",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 31419,
            "upload_time": "2025-01-22T10:52:49",
            "upload_time_iso_8601": "2025-01-22T10:52:49.002437Z",
            "url": "https://files.pythonhosted.org/packages/3f/89/f95c8bb125196f7f2271922e5c34254852b4546890e7da301fa7c613f074/wcs-0.2.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-01-22 10:52:49",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "rasdaman",
    "github_project": "wcs-python-client",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "wcs"
}
        
Elapsed time: 0.50202s