Skip to main content

Overview

The OGC Web Coverage Service (WCS) standard 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.

Installation

pip install wcs

Examples

List Coverages

The example below illustrates how to get a list of BasicCoverage objects for all coverages (datacubes) on the server, and extract various details for a particular coverage.

First we need to create a WebCoverageService object. Optionally, a username and a password may be specified, if the endpoint requires them.

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), with basic information such as a WGS 84 bounding box and a native bounding box:

coverages = service.list_coverages()

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

cov = coverages['dominant_leaf_type_20m']

print(cov)
dominant_leaf_type_20m:
  subtype: ReferenceableGridCoverage
  crs: OGC:AnsiDate+EPSG:3035
  bbox:
    time:
      low: "2012-01-01"
      high: "2015-01-01"
      crs: OGC:AnsiDate
    Y:
      low: 900000
      high: 5500000
      crs: EPSG:3035
    X:
      low: 900000
      high: 7400000
      crs: EPSG:3035
  WGS84 bbox:
    Lon:
      low: -56.50514190170437
      high: 72.9061049341568
      crs: EPSG:4326
    Lat:
      low: 24.28417068794856
      high: 72.66326966834436
      crs: EPSG:4326
  size in bytes: 113000000001
  additional params:
    title: Dominant Leaf Type (2012-2015)
    sizeInBytesWithPyramidLevels: 122417133472

Examples for extracting individual details of the coverage:

# 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 object:

cov = service.list_full_info('dominant_leaf_type_20m')

# print all information

print(cov)
  crs: OGC:AnsiDate+EPSG:3035
  bbox:
    time:
      low: "2012-01-01"
      high: "2015-01-01"
      crs: OGC:AnsiDate
      uom: d
      type: irregular
      coefficients: ["2012-01-01", "2015-01-01"]
    Y:
      low: 900000
      high: 5500000
      crs: EPSG:3035
      uom: metre
      resolution: -20.0
      type: regular
    X:
      low: 900000
      high: 7400000
      crs: EPSG:3035
      uom: metre
      resolution: 20.0
      type: regular
  grid_bbox:
    i:
      low: 0
      high: 1
      resolution: 1
      type: regular
    j:
      low: -125000
      high: 104999
      resolution: 1
      type: regular
    k:
      low: 0
      high: 324999
      resolution: 1
      type: regular
  range_type:
    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). According to the 2020 State of Europe’s Forest report, approximately 70% of European forests are dominated by broadleaf deciduous trees while the remaining 30% are dominated by evergreen coniferous trees. Broadleaf and coniferous forests represent distinct habitat types and require different ecological considerations and management approaches. For example, coniferous forests are often more fire-resistant than broadleaf forests, but coniferous forests are also more vulnerable to infestations from insects such as bark beetles and processionary moths. There are also differences with regards to carbon storage and sequestration—broadleaf forests typically have higher tree density and larger average trunk diameter while coniferous forests have a longer growing season and deeper root systems. The High Resolution Layer Dominant Leaf Type product allows users to identify and track changes in the dominant leaf type of all European tree cover. This data can be used to monitor the health of ecosystems, identify areas experiencing high levels of deforestation or reforestation, manage natural resources, inform climate change mitigation strategies, and support biodiversity conservation efforts. Because this is a high resolution product, which covers the entirety of Europe, it can be used to inform policy decisions from the regional to the continental scale. The product is currently on a three-year update cycle, but in 2024 these will become annual, beginning from the 2019 reference year.
        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 object, except its crs attribute is None.

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 objects corresponding to the bands of the coverage. Check the documentation of RangeType for full details.

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:

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, with funding from the Horizon Europe programme under grant agreement No 101059238.

Release files for wcs 0.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wcs 0.4.1
File Size Uploaded
wcs-0.4.1.tar.gz 34.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for wcs 0.4.1
File Interpreter ABI Platform
wcs-0.4.1-py3-none-any.whl Python 3 none any Details

Total release size: 60.6 kB

Release files / wcs-0.4.1.tar.gz

Download URL wcs-0.4.1.tar.gz
Size 34.8 kB
Tags Source
SHA-256 checksum
How to use checksums
35d3beef12fc1c4a0c50f868ef9d95fb96f586b0904bf2f0ed5b6d23c359a0bc
BLAKE2b-256 checksum
How to use checksums
39ccb6afa282faf2c9a6b880bd073ed582be67725308861b3a7f7127a42cdbdc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.

Transparency log

Release files / wcs-0.4.1-py3-none-any.whl

Download URL wcs-0.4.1-py3-none-any.whl
Size 25.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2b39bca3de9a61a1e451d6ad806edea51472f3578aefa93dd973936c3f6bd979
BLAKE2b-256 checksum
How to use checksums
2a3f325bb40fee26b3aa89044f9ff972dd82b3aa8dbbfe6387cd5d9bd1f04c0e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.1 This release

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.5

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page