Skip to content

Commit 70d691b

Browse files
committed
- add example usage in the README
- simplify model classes: - remove separate WGS84BoundingBox class, and replace BasicCoverage.wgs84_bbox with lon and lat Axis attributes - remove separate GridBoundingBox class, and change FullCoverage.grid_bbox to a BoundingBox object with None crs - remove the Crs class, replace all crs attributes to contain only the string as parsed from the WCS server - add a utility Crs class that allows to convert a CRS identifier to shorthand notation - change fields in RangeType from a dict to a list of Field objects - add __getitem__ methods to RangeType and BoundingBox for easier access to the fields/axes - automate service tests
1 parent 719709c commit 70d691b

7 files changed

Lines changed: 451 additions & 267 deletions

File tree

README.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from docutils.nodes import description
2+
13
# Overview
24

35
The [OGC Web Coverage Service (WCS) standard](https://www.ogc.org/standards/wcs)
@@ -13,22 +15,195 @@ given WCS endpoint.
1315

1416
# Examples
1517

18+
The example below illustrates how to get a list of
19+
[BasicCoverage](autoapi/wcs/model/index.html#wcs.model.BasicCoverage)
20+
objects for all coverages on the server, and extract various details
21+
for a particular coverage.
22+
1623
```python
1724
from wcs.service import WebCoverageService
25+
from wcs.model import Crs
1826

1927
wcs_endpoint = "https://ows.rasdaman.org/rasdaman/ows"
2028
service = WebCoverageService(wcs_endpoint)
2129

2230
# get a list of all coverages, with basic information such
2331
# as a WGS 84 bounding box and a native bounding box
2432
coverages = service.list_coverages()
33+
34+
# get the AvgLandTemp coverage object, see BasicCoverage
35+
# in the API reference
2536
avg_land_temp = coverages['AvgLandTemp']
2637

38+
# print all information
39+
print(avg_land_temp)
40+
41+
# AvgLandTemp:
42+
# subtype: ReferenceableGridCoverage
43+
# native CRS: OGC:AnsiDate+EPSG:4326
44+
# geo bbox:
45+
# ansi:
46+
# min: "2000-02-01"
47+
# max: "2015-06-01"
48+
# crs: OGC:AnsiDate
49+
# Lat:
50+
# min: -90
51+
# max: 90
52+
# crs: EPSG:4326
53+
# Lon:
54+
# min: -180
55+
# max: 180
56+
# crs: EPSG:4326
57+
# lon/lat bbox:
58+
# Lon:
59+
# min: -180
60+
# max: 180
61+
# crs: EPSG:4326
62+
# Lat:
63+
# min: -90
64+
# max: 90
65+
# crs: EPSG:4326
66+
# size in bytes: 4809618404
67+
68+
# coverage subtype
69+
print(avg_land_temp.subtype)
70+
# ReferenceableGridCoverage
71+
72+
# coverage bounding box, containing the CRS and axes
73+
bbox = avg_land_temp.bbox
74+
75+
# full coverage crs identifier
76+
print(bbox.crs)
77+
# https://www.opengis.net/def/crs-compound?
78+
# 1=https://www.opengis.net/def/crs/OGC/0/AnsiDate&
79+
# 2=https://www.opengis.net/def/crs/EPSG/0/4326
80+
81+
# coverage crs identifier in shorthand notation
82+
print(Crs.to_short_notation(bbox.crs))
83+
# OGC:AnsiDate+EPSG:4326
84+
85+
# get information for the first axis; as it is a temporal axis,
86+
# the lower_bound and upper_bound are datetime.datetime objects.
87+
axis = bbox[0]
88+
name = axis.name
89+
lower_bound = axis.low
90+
upper_bound = axis.high
91+
print(f'{name}({lower_bound} - {upper_bound})')
92+
# ansi(2000-02-01 00:00:00+00:00 - 2015-06-01 00:00:00+00:00)
93+
94+
# get information for the Lat axis
95+
axis = bbox['Lat']
96+
print(axis.name)
97+
# Lat
98+
99+
# get size in bytes if available
100+
if avg_land_temp.size_bytes is not None:
101+
print(avg_land_temp.size_bytes)
102+
# 4809618404
103+
104+
```
105+
106+
The above example gets basic information about the coverage
107+
through what is published in the WCS GetCapabilities response.
108+
More detailed information can be retrieved with the
109+
`list_full_info` method, which returns a
110+
[FullCoverage](autoapi/wcs/model/index.html#wcs.model.FullCoverage)
111+
object.
112+
113+
```python
114+
from wcs.service import WebCoverageService
115+
116+
wcs_endpoint = "https://ows.rasdaman.org/rasdaman/ows"
117+
service = WebCoverageService(wcs_endpoint)
118+
27119
# get full information for a particular coverage by
28120
# parsing its DescribeCoverage document from the WCS server
29121
full_avg_land_temp = service.list_full_info('AvgLandTemp')
122+
123+
# print all information
124+
print(full_avg_land_temp)
125+
126+
# AvgLandTemp:
127+
# native CRS: OGC:AnsiDate+EPSG:4326
128+
# geo bbox:
129+
# ansi:
130+
# min: "2000-02-01"
131+
# max: "2015-06-01"
132+
# crs: OGC:AnsiDate
133+
# uom: d
134+
# type: irregular
135+
# coefficients: ["2000-02-01", "2000-03-01", ...
136+
# "2015-05-01", "2015-06-01"]
137+
# Lat:
138+
# min: -90
139+
# max: 90
140+
# crs: EPSG:4326
141+
# uom: degree
142+
# resolution: -0.1
143+
# type: regular
144+
# Lon:
145+
# min: -180
146+
# max: 180
147+
# crs: EPSG:4326
148+
# uom: degree
149+
# resolution: 0.1
150+
# type: regular
151+
# grid bbox:
152+
# i:
153+
# min: 0
154+
# max: 184
155+
# resolution: 1
156+
# type: regular
157+
# j:
158+
# min: 0
159+
# max: 1799
160+
# resolution: 1
161+
# type: regular
162+
# k:
163+
# min: 0
164+
# max: 3599
165+
# resolution: 1
166+
# type: regular
167+
# range type fields:
168+
# Gray:
169+
# type: Quantity
170+
# label: Gray
171+
# definition: http://www.opengis.net/def/dataType/OGC/0/float32
172+
# nil values: 99999
173+
# uom: 10^0
174+
# metadata:
175+
# {
176+
# "covMetadata": null
177+
# }
178+
179+
180+
# In addition to the geo bounding box in native CRS, the
181+
# `FullCoverage` object also has a `grid_bbox`, which contains
182+
# the integer grid axis bounds of the coverage. This is the same
183+
# type of `BoundingBox` object, except the `crs` is None.
184+
print(full_avg_land_temp.grid_bbox)
185+
186+
# The range_type indicates the structure of the cell values
187+
# of the coverage. It contains a `fields` attribute, which is
188+
# a list of `Field` object corresponding to the bands of the
189+
# coverage. Check the documentation of RangeType for full details.
190+
range_type = full_avg_land_temp.range_type
191+
all_fields = range_type.fields
192+
field = range_type['Gray'] # or range_type[0]
193+
194+
# get all properties of the field
195+
label = field.label
196+
description = field.description
197+
definition = field.definition
198+
nil_values = field.nil_values
199+
if field.is_quantity:
200+
uom = field.uom
201+
else:
202+
codespace = field.codespace
30203
```
31204

205+
206+
32207
# Contributing
33208

34209
The directory structure is as follows:

tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Unit tests that should be executed with pytest."""

0 commit comments

Comments
 (0)