pystac-ext-view 1.0.0rc0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pystac_ext_view-1.0.0rc0/.gitignore +163 -0
- pystac_ext_view-1.0.0rc0/PKG-INFO +37 -0
- pystac_ext_view-1.0.0rc0/README.md +13 -0
- pystac_ext_view-1.0.0rc0/pyproject.toml +36 -0
- pystac_ext_view-1.0.0rc0/pystac/extensions/py.typed +0 -0
- pystac_ext_view-1.0.0rc0/pystac/extensions/view.py +314 -0
- pystac_ext_view-1.0.0rc0/tests/cassettes/test_view/test_azimuth.yaml +120 -0
- pystac_ext_view-1.0.0rc0/tests/cassettes/test_view/test_incidence_angle.yaml +120 -0
- pystac_ext_view-1.0.0rc0/tests/cassettes/test_view/test_off_nadir.yaml +120 -0
- pystac_ext_view-1.0.0rc0/tests/cassettes/test_view/test_sun_azimuth.yaml +120 -0
- pystac_ext_view-1.0.0rc0/tests/cassettes/test_view/test_sun_elevation.yaml +120 -0
- pystac_ext_view-1.0.0rc0/tests/cassettes/test_view/test_validate_view.yaml +120 -0
- pystac_ext_view-1.0.0rc0/tests/data-files/collection-with-summaries.json +69 -0
- pystac_ext_view-1.0.0rc0/tests/data-files/example-landsat8.json +96 -0
- pystac_ext_view-1.0.0rc0/tests/test_view.py +358 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
*.pyc
|
|
2
|
+
*.egg-info
|
|
3
|
+
*.eggs
|
|
4
|
+
.DS_Store
|
|
5
|
+
data
|
|
6
|
+
config.json
|
|
7
|
+
stdout*
|
|
8
|
+
/integration*
|
|
9
|
+
.idea
|
|
10
|
+
.vscode
|
|
11
|
+
.actrc
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# Sphinx documentation
|
|
15
|
+
.ipynb_checkpoints/
|
|
16
|
+
|
|
17
|
+
docs/tutorials/pystac-example*
|
|
18
|
+
docs/tutorials/spacenet-stac/
|
|
19
|
+
docs/tutorials/spacenet-cog-stac/
|
|
20
|
+
docs/tutorials/data/
|
|
21
|
+
docs/quickstart_stac/
|
|
22
|
+
|
|
23
|
+
# Byte-compiled / optimized / DLL files
|
|
24
|
+
__pycache__/
|
|
25
|
+
*.py[cod]
|
|
26
|
+
*$py.class
|
|
27
|
+
|
|
28
|
+
# C extensions
|
|
29
|
+
*.so
|
|
30
|
+
|
|
31
|
+
# Distribution / packaging
|
|
32
|
+
.Python
|
|
33
|
+
build/
|
|
34
|
+
develop-eggs/
|
|
35
|
+
dist/
|
|
36
|
+
downloads/
|
|
37
|
+
eggs/
|
|
38
|
+
.eggs/
|
|
39
|
+
lib/
|
|
40
|
+
lib64/
|
|
41
|
+
parts/
|
|
42
|
+
sdist/
|
|
43
|
+
var/
|
|
44
|
+
wheels/
|
|
45
|
+
share/python-wheels/
|
|
46
|
+
*.egg-info/
|
|
47
|
+
.installed.cfg
|
|
48
|
+
*.egg
|
|
49
|
+
MANIFEST
|
|
50
|
+
|
|
51
|
+
# PyInstaller
|
|
52
|
+
# Usually these files are written by a python script from a template
|
|
53
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
54
|
+
*.manifest
|
|
55
|
+
*.spec
|
|
56
|
+
|
|
57
|
+
# Installer logs
|
|
58
|
+
pip-log.txt
|
|
59
|
+
pip-delete-this-directory.txt
|
|
60
|
+
|
|
61
|
+
# Unit test / coverage reports
|
|
62
|
+
htmlcov/
|
|
63
|
+
.tox/
|
|
64
|
+
.nox/
|
|
65
|
+
.coverage
|
|
66
|
+
.coverage.*
|
|
67
|
+
.cache
|
|
68
|
+
nosetests.xml
|
|
69
|
+
coverage.xml
|
|
70
|
+
*.cover
|
|
71
|
+
*.py,cover
|
|
72
|
+
.hypothesis/
|
|
73
|
+
.pytest_cache/
|
|
74
|
+
cover/
|
|
75
|
+
|
|
76
|
+
# Translations
|
|
77
|
+
*.mo
|
|
78
|
+
*.pot
|
|
79
|
+
|
|
80
|
+
# Django stuff:
|
|
81
|
+
*.log
|
|
82
|
+
local_settings.py
|
|
83
|
+
db.sqlite3
|
|
84
|
+
db.sqlite3-journal
|
|
85
|
+
|
|
86
|
+
# Flask stuff:
|
|
87
|
+
instance/
|
|
88
|
+
.webassets-cache
|
|
89
|
+
|
|
90
|
+
# Scrapy stuff:
|
|
91
|
+
.scrapy
|
|
92
|
+
|
|
93
|
+
# Sphinx documentation
|
|
94
|
+
docs/_build/
|
|
95
|
+
|
|
96
|
+
# PyBuilder
|
|
97
|
+
.pybuilder/
|
|
98
|
+
target/
|
|
99
|
+
|
|
100
|
+
# Jupyter Notebook
|
|
101
|
+
.ipynb_checkpoints
|
|
102
|
+
|
|
103
|
+
# IPython
|
|
104
|
+
profile_default/
|
|
105
|
+
ipython_config.py
|
|
106
|
+
|
|
107
|
+
# pyenv
|
|
108
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
109
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
110
|
+
# .python-version
|
|
111
|
+
|
|
112
|
+
# pipenv
|
|
113
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
114
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
115
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
116
|
+
# install all needed dependencies.
|
|
117
|
+
# Pipfile.lock
|
|
118
|
+
|
|
119
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
120
|
+
__pypackages__/
|
|
121
|
+
|
|
122
|
+
# Celery stuff
|
|
123
|
+
celerybeat-schedule
|
|
124
|
+
celerybeat.pid
|
|
125
|
+
|
|
126
|
+
# SageMath parsed files
|
|
127
|
+
*.sage.py
|
|
128
|
+
|
|
129
|
+
# Environments
|
|
130
|
+
.env
|
|
131
|
+
.venv
|
|
132
|
+
env/
|
|
133
|
+
venv/
|
|
134
|
+
ENV/
|
|
135
|
+
env.bak/
|
|
136
|
+
venv.bak/
|
|
137
|
+
|
|
138
|
+
# Spyder project settings
|
|
139
|
+
.spyderproject
|
|
140
|
+
.spyproject
|
|
141
|
+
|
|
142
|
+
# Rope project settings
|
|
143
|
+
.ropeproject
|
|
144
|
+
|
|
145
|
+
# mkdocs documentation
|
|
146
|
+
/site
|
|
147
|
+
|
|
148
|
+
# mypy
|
|
149
|
+
.mypy_cache/
|
|
150
|
+
.dmypy.json
|
|
151
|
+
dmypy.json
|
|
152
|
+
|
|
153
|
+
# Pyre type checker
|
|
154
|
+
.pyre/
|
|
155
|
+
|
|
156
|
+
# pytype static type analyzer
|
|
157
|
+
.pytype/
|
|
158
|
+
|
|
159
|
+
# Cython debug symbols
|
|
160
|
+
cython_debug/
|
|
161
|
+
|
|
162
|
+
# asv environments
|
|
163
|
+
.asv
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pystac-ext-view
|
|
3
|
+
Version: 1.0.0rc0
|
|
4
|
+
Summary: View extension for PySTAC
|
|
5
|
+
Project-URL: Documentation, https://pystac.readthedocs.io
|
|
6
|
+
Project-URL: Repository, https://github.com/stac-utils/pystac
|
|
7
|
+
Project-URL: Issues, https://github.com/stac-utils/pystac/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/stac-utils/pystac/blob/main/CHANGELOG.md
|
|
9
|
+
Project-URL: Discussions, https://github.com/radiantearth/stac-spec/discussions/categories/stac-software
|
|
10
|
+
License: Apache-2.0
|
|
11
|
+
Keywords: STAC,catalog,imagery,pystac,raster,view
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
|
+
Classifier: Natural Language :: English
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: pystac-core
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# pystac-ext-view
|
|
26
|
+
|
|
27
|
+
[PySTAC](https://pypi.org/project/pystac/) extension package for the [View Geometry Extension](https://github.com/stac-extensions/view).
|
|
28
|
+
This extension provides fields for describing the angle of observation for geospatial data, including off-nadir angle, incidence angle, azimuth, and sun geometry.
|
|
29
|
+
|
|
30
|
+
## Supported versions
|
|
31
|
+
|
|
32
|
+
- [v1.0.0](https://stac-extensions.github.io/view/v1.0.0/schema.json)
|
|
33
|
+
|
|
34
|
+
## Versioning
|
|
35
|
+
|
|
36
|
+
This package's version corresponds to the version of the extension specification it targets.
|
|
37
|
+
When we release updates to the package code without changing the target extension version, we use [post releases](https://packaging.python.org/en/latest/discussions/versioning/#post-releases), e.g. `1.0.0.post1`.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# pystac-ext-view
|
|
2
|
+
|
|
3
|
+
[PySTAC](https://pypi.org/project/pystac/) extension package for the [View Geometry Extension](https://github.com/stac-extensions/view).
|
|
4
|
+
This extension provides fields for describing the angle of observation for geospatial data, including off-nadir angle, incidence angle, azimuth, and sun geometry.
|
|
5
|
+
|
|
6
|
+
## Supported versions
|
|
7
|
+
|
|
8
|
+
- [v1.0.0](https://stac-extensions.github.io/view/v1.0.0/schema.json)
|
|
9
|
+
|
|
10
|
+
## Versioning
|
|
11
|
+
|
|
12
|
+
This package's version corresponds to the version of the extension specification it targets.
|
|
13
|
+
When we release updates to the package code without changing the target extension version, we use [post releases](https://packaging.python.org/en/latest/discussions/versioning/#post-releases), e.g. `1.0.0.post1`.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "pystac-ext-view"
|
|
3
|
+
description = "View extension for PySTAC"
|
|
4
|
+
readme = "README.md"
|
|
5
|
+
version = "1.0.0-rc.0"
|
|
6
|
+
authors = []
|
|
7
|
+
maintainers = []
|
|
8
|
+
keywords = ["pystac", "imagery", "raster", "catalog", "STAC", "view"]
|
|
9
|
+
license = { text = "Apache-2.0" }
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 5 - Production/Stable",
|
|
12
|
+
"Intended Audience :: Developers",
|
|
13
|
+
"License :: OSI Approved :: Apache Software License",
|
|
14
|
+
"Natural Language :: English",
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Programming Language :: Python :: 3.10",
|
|
17
|
+
"Programming Language :: Python :: 3.11",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Programming Language :: Python :: 3.13",
|
|
20
|
+
]
|
|
21
|
+
requires-python = ">=3.10"
|
|
22
|
+
dependencies = ["pystac-core"]
|
|
23
|
+
|
|
24
|
+
[project.urls]
|
|
25
|
+
Documentation = "https://pystac.readthedocs.io"
|
|
26
|
+
Repository = "https://github.com/stac-utils/pystac"
|
|
27
|
+
Issues = "https://github.com/stac-utils/pystac/issues"
|
|
28
|
+
Changelog = "https://github.com/stac-utils/pystac/blob/main/CHANGELOG.md"
|
|
29
|
+
Discussions = "https://github.com/radiantearth/stac-spec/discussions/categories/stac-software"
|
|
30
|
+
|
|
31
|
+
[build-system]
|
|
32
|
+
requires = ["hatchling"]
|
|
33
|
+
build-backend = "hatchling.build"
|
|
34
|
+
|
|
35
|
+
[tool.hatch.build.targets.wheel]
|
|
36
|
+
packages = ["pystac"]
|
|
File without changes
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
"""Implement the :stac-ext:`View Geometry Extension <view>`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Iterable
|
|
6
|
+
from typing import Any, Generic, Literal, TypeVar, cast
|
|
7
|
+
|
|
8
|
+
import pystac
|
|
9
|
+
from pystac.extensions.base import (
|
|
10
|
+
ExtensionManagementMixin,
|
|
11
|
+
PropertiesExtension,
|
|
12
|
+
SummariesExtension,
|
|
13
|
+
)
|
|
14
|
+
from pystac.extensions.hooks import ExtensionHooks
|
|
15
|
+
from pystac.summaries import RangeSummary
|
|
16
|
+
|
|
17
|
+
#: Generalized version of :class:`~pystac.Item`, :class:`~pystac.Asset`
|
|
18
|
+
#: or :class:`~pystac.ItemAssetDefinition`
|
|
19
|
+
T = TypeVar("T", pystac.Item, pystac.Asset, pystac.ItemAssetDefinition)
|
|
20
|
+
|
|
21
|
+
SCHEMA_URI: str = "https://stac-extensions.github.io/view/v1.0.0/schema.json"
|
|
22
|
+
PREFIX: str = "view:"
|
|
23
|
+
|
|
24
|
+
OFF_NADIR_PROP: str = PREFIX + "off_nadir"
|
|
25
|
+
INCIDENCE_ANGLE_PROP: str = PREFIX + "incidence_angle"
|
|
26
|
+
AZIMUTH_PROP: str = PREFIX + "azimuth"
|
|
27
|
+
SUN_AZIMUTH_PROP: str = PREFIX + "sun_azimuth"
|
|
28
|
+
SUN_ELEVATION_PROP: str = PREFIX + "sun_elevation"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ViewExtension(
|
|
32
|
+
Generic[T],
|
|
33
|
+
PropertiesExtension,
|
|
34
|
+
ExtensionManagementMixin[pystac.Item | pystac.Collection],
|
|
35
|
+
):
|
|
36
|
+
"""An abstract class that can be used to extend the properties of an
|
|
37
|
+
:class:`~pystac.Item` with properties from the :stac-ext:`View Geometry
|
|
38
|
+
Extension <view>`. This class is generic over the type of STAC Object to be
|
|
39
|
+
extended (e.g. :class:`~pystac.Item`, :class:`~pystac.Asset`).
|
|
40
|
+
|
|
41
|
+
To create a concrete instance of :class:`ViewExtension`, use the
|
|
42
|
+
:meth:`ViewExtension.ext` method. For example:
|
|
43
|
+
|
|
44
|
+
.. code-block:: python
|
|
45
|
+
|
|
46
|
+
>>> item: pystac.Item = ...
|
|
47
|
+
>>> view_ext = ViewExtension.ext(item)
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
name: Literal["view"] = "view"
|
|
51
|
+
|
|
52
|
+
def apply(
|
|
53
|
+
self,
|
|
54
|
+
off_nadir: float | None = None,
|
|
55
|
+
incidence_angle: float | None = None,
|
|
56
|
+
azimuth: float | None = None,
|
|
57
|
+
sun_azimuth: float | None = None,
|
|
58
|
+
sun_elevation: float | None = None,
|
|
59
|
+
) -> None:
|
|
60
|
+
"""Applies View Geometry extension properties to the extended
|
|
61
|
+
:class:`~pystac.Item`.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
off_nadir : The angle from the sensor between nadir (straight down)
|
|
65
|
+
and the scene center. Measured in degrees (0-90).
|
|
66
|
+
incidence_angle : The incidence angle is the angle between the
|
|
67
|
+
vertical (normal) to the intercepting surface and the line of sight
|
|
68
|
+
back to the satellite at the scene center. Measured in degrees (0-90).
|
|
69
|
+
azimuth : Viewing azimuth angle. The angle measured from the
|
|
70
|
+
sub-satellite point (point on the ground below the platform) between
|
|
71
|
+
the scene center and true north. Measured clockwise from north in
|
|
72
|
+
degrees (0-360).
|
|
73
|
+
sun_azimuth : Sun azimuth angle. From the scene center point on the
|
|
74
|
+
ground, this is the angle between truth north and the sun. Measured
|
|
75
|
+
clockwise in degrees (0-360).
|
|
76
|
+
sun_elevation : Sun elevation angle. The angle from the tangent of
|
|
77
|
+
the scene center point to the sun. Measured from the horizon in
|
|
78
|
+
degrees (0-90).
|
|
79
|
+
"""
|
|
80
|
+
self.off_nadir = off_nadir
|
|
81
|
+
self.incidence_angle = incidence_angle
|
|
82
|
+
self.azimuth = azimuth
|
|
83
|
+
self.sun_azimuth = sun_azimuth
|
|
84
|
+
self.sun_elevation = sun_elevation
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def off_nadir(self) -> float | None:
|
|
88
|
+
"""Get or sets the angle from the sensor between nadir (straight down)
|
|
89
|
+
and the scene center. Measured in degrees (0-90).
|
|
90
|
+
"""
|
|
91
|
+
return self._get_property(OFF_NADIR_PROP, float)
|
|
92
|
+
|
|
93
|
+
@off_nadir.setter
|
|
94
|
+
def off_nadir(self, v: float | None) -> None:
|
|
95
|
+
self._set_property(OFF_NADIR_PROP, v)
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def incidence_angle(self) -> float | None:
|
|
99
|
+
"""Get or sets the incidence angle is the angle between the vertical (normal)
|
|
100
|
+
to the intercepting surface and the line of sight back to the satellite at
|
|
101
|
+
the scene center. Measured in degrees (0-90).
|
|
102
|
+
"""
|
|
103
|
+
return self._get_property(INCIDENCE_ANGLE_PROP, float)
|
|
104
|
+
|
|
105
|
+
@incidence_angle.setter
|
|
106
|
+
def incidence_angle(self, v: float | None) -> None:
|
|
107
|
+
self._set_property(INCIDENCE_ANGLE_PROP, v)
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def azimuth(self) -> float | None:
|
|
111
|
+
"""Get or sets the viewing azimuth angle.
|
|
112
|
+
|
|
113
|
+
The angle measured from the sub-satellite
|
|
114
|
+
point (point on the ground below the platform) between the scene center and true
|
|
115
|
+
north. Measured clockwise from north in degrees (0-360).
|
|
116
|
+
"""
|
|
117
|
+
return self._get_property(AZIMUTH_PROP, float)
|
|
118
|
+
|
|
119
|
+
@azimuth.setter
|
|
120
|
+
def azimuth(self, v: float | None) -> None:
|
|
121
|
+
self._set_property(AZIMUTH_PROP, v)
|
|
122
|
+
|
|
123
|
+
@property
|
|
124
|
+
def sun_azimuth(self) -> float | None:
|
|
125
|
+
"""Get or sets the sun azimuth angle.
|
|
126
|
+
|
|
127
|
+
From the scene center point on the ground, this
|
|
128
|
+
is the angle between truth north and the sun. Measured clockwise in
|
|
129
|
+
degrees (0-360).
|
|
130
|
+
"""
|
|
131
|
+
return self._get_property(SUN_AZIMUTH_PROP, float)
|
|
132
|
+
|
|
133
|
+
@sun_azimuth.setter
|
|
134
|
+
def sun_azimuth(self, v: float | None) -> None:
|
|
135
|
+
self._set_property(SUN_AZIMUTH_PROP, v)
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def sun_elevation(self) -> float | None:
|
|
139
|
+
"""Get or sets the sun elevation angle. The angle from the tangent of the scene
|
|
140
|
+
center point to the sun. Measured from the horizon in degrees (0-90).
|
|
141
|
+
"""
|
|
142
|
+
return self._get_property(SUN_ELEVATION_PROP, float)
|
|
143
|
+
|
|
144
|
+
@sun_elevation.setter
|
|
145
|
+
def sun_elevation(self, v: float | None) -> None:
|
|
146
|
+
self._set_property(SUN_ELEVATION_PROP, v)
|
|
147
|
+
|
|
148
|
+
@classmethod
|
|
149
|
+
def get_schema_uri(cls) -> str:
|
|
150
|
+
return SCHEMA_URI
|
|
151
|
+
|
|
152
|
+
@classmethod
|
|
153
|
+
def ext(cls, obj: T, add_if_missing: bool = False) -> ViewExtension[T]:
|
|
154
|
+
"""Extends the given STAC Object with properties from the :stac-ext:`View
|
|
155
|
+
Geometry Extension <scientific>`.
|
|
156
|
+
|
|
157
|
+
This extension can be applied to instances of :class:`~pystac.Item` or
|
|
158
|
+
:class:`~pystac.Asset`.
|
|
159
|
+
|
|
160
|
+
Raises:
|
|
161
|
+
|
|
162
|
+
pystac.ExtensionTypeError : If an invalid object type is passed.
|
|
163
|
+
"""
|
|
164
|
+
if isinstance(obj, pystac.Item):
|
|
165
|
+
cls.ensure_has_extension(obj, add_if_missing)
|
|
166
|
+
return cast(ViewExtension[T], ItemViewExtension(obj))
|
|
167
|
+
elif isinstance(obj, pystac.Asset):
|
|
168
|
+
cls.ensure_owner_has_extension(obj, add_if_missing)
|
|
169
|
+
return cast(ViewExtension[T], AssetViewExtension(obj))
|
|
170
|
+
elif isinstance(obj, pystac.ItemAssetDefinition):
|
|
171
|
+
cls.ensure_owner_has_extension(obj, add_if_missing)
|
|
172
|
+
return cast(ViewExtension[T], ItemAssetsViewExtension(obj))
|
|
173
|
+
else:
|
|
174
|
+
raise pystac.ExtensionTypeError(cls._ext_error_message(obj))
|
|
175
|
+
|
|
176
|
+
@classmethod
|
|
177
|
+
def summaries(
|
|
178
|
+
cls, obj: pystac.Collection, add_if_missing: bool = False
|
|
179
|
+
) -> SummariesViewExtension:
|
|
180
|
+
"""Returns the extended summaries object for the given collection."""
|
|
181
|
+
cls.ensure_has_extension(obj, add_if_missing)
|
|
182
|
+
return SummariesViewExtension(obj)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class ItemViewExtension(ViewExtension[pystac.Item]):
|
|
186
|
+
"""A concrete implementation of :class:`ViewExtension` on an :class:`~pystac.Item`
|
|
187
|
+
that extends the properties of the Item to include properties defined in the
|
|
188
|
+
:stac-ext:`View Geometry Extension <view>`.
|
|
189
|
+
|
|
190
|
+
This class should generally not be instantiated directly. Instead, call
|
|
191
|
+
:meth:`ViewExtension.ext` on an :class:`~pystac.Item` to extend it.
|
|
192
|
+
"""
|
|
193
|
+
|
|
194
|
+
item: pystac.Item
|
|
195
|
+
"""The :class:`~pystac.Item` being extended."""
|
|
196
|
+
|
|
197
|
+
properties: dict[str, Any]
|
|
198
|
+
"""The :class:`~pystac.Item` properties, including extension properties."""
|
|
199
|
+
|
|
200
|
+
def __init__(self, item: pystac.Item):
|
|
201
|
+
self.item = item
|
|
202
|
+
self.properties = item.properties
|
|
203
|
+
|
|
204
|
+
def __repr__(self) -> str:
|
|
205
|
+
return f"<ItemViewExtension Item id={self.item.id}>"
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class AssetViewExtension(ViewExtension[pystac.Asset]):
|
|
209
|
+
"""A concrete implementation of :class:`ViewExtension` on an :class:`~pystac.Asset`
|
|
210
|
+
that extends the Asset fields to include properties defined in the
|
|
211
|
+
:stac-ext:`View Geometry Extension <view>`.
|
|
212
|
+
|
|
213
|
+
This class should generally not be instantiated directly. Instead, call
|
|
214
|
+
:meth:`ViewExtension.ext` on an :class:`~pystac.Asset` to extend it.
|
|
215
|
+
"""
|
|
216
|
+
|
|
217
|
+
asset_href: str
|
|
218
|
+
"""The ``href`` value of the :class:`~pystac.Asset` being extended."""
|
|
219
|
+
|
|
220
|
+
properties: dict[str, Any]
|
|
221
|
+
"""The :class:`~pystac.Asset` fields, including extension properties."""
|
|
222
|
+
|
|
223
|
+
additional_read_properties: Iterable[dict[str, Any]] | None = None
|
|
224
|
+
"""If present, this will be a list containing 1 dictionary representing the
|
|
225
|
+
properties of the owning :class:`~pystac.Item`."""
|
|
226
|
+
|
|
227
|
+
def __init__(self, asset: pystac.Asset):
|
|
228
|
+
self.asset_href = asset.href
|
|
229
|
+
self.properties = asset.extra_fields
|
|
230
|
+
if asset.owner and isinstance(asset.owner, pystac.Item):
|
|
231
|
+
self.additional_read_properties = [asset.owner.properties]
|
|
232
|
+
|
|
233
|
+
def __repr__(self) -> str:
|
|
234
|
+
return f"<AssetViewExtension Asset href={self.asset_href}>"
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
class ItemAssetsViewExtension(ViewExtension[pystac.ItemAssetDefinition]):
|
|
238
|
+
properties: dict[str, Any]
|
|
239
|
+
asset_defn: pystac.ItemAssetDefinition
|
|
240
|
+
|
|
241
|
+
def __init__(self, item_asset: pystac.ItemAssetDefinition):
|
|
242
|
+
self.asset_defn = item_asset
|
|
243
|
+
self.properties = item_asset.properties
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
class SummariesViewExtension(SummariesExtension):
|
|
247
|
+
"""A concrete implementation of :class:`~pystac.extensions.base.SummariesExtension`
|
|
248
|
+
that extends the ``summaries`` field of a :class:`~pystac.Collection` to include
|
|
249
|
+
properties defined in the :stac-ext:`View Object Extension <view>`.
|
|
250
|
+
"""
|
|
251
|
+
|
|
252
|
+
@property
|
|
253
|
+
def off_nadir(self) -> RangeSummary[float] | None:
|
|
254
|
+
"""Get or sets the summary of :attr:`ViewExtension.off_nadir` values for
|
|
255
|
+
this Collection.
|
|
256
|
+
"""
|
|
257
|
+
return self.summaries.get_range(OFF_NADIR_PROP)
|
|
258
|
+
|
|
259
|
+
@off_nadir.setter
|
|
260
|
+
def off_nadir(self, v: RangeSummary[float] | None) -> None:
|
|
261
|
+
self._set_summary(OFF_NADIR_PROP, v)
|
|
262
|
+
|
|
263
|
+
@property
|
|
264
|
+
def incidence_angle(self) -> RangeSummary[float] | None:
|
|
265
|
+
"""Get or sets the summary of :attr:`ViewExtension.incidence_angle` values
|
|
266
|
+
for this Collection.
|
|
267
|
+
"""
|
|
268
|
+
return self.summaries.get_range(INCIDENCE_ANGLE_PROP)
|
|
269
|
+
|
|
270
|
+
@incidence_angle.setter
|
|
271
|
+
def incidence_angle(self, v: RangeSummary[float] | None) -> None:
|
|
272
|
+
self._set_summary(INCIDENCE_ANGLE_PROP, v)
|
|
273
|
+
|
|
274
|
+
@property
|
|
275
|
+
def azimuth(self) -> RangeSummary[float] | None:
|
|
276
|
+
"""Get or sets the summary of :attr:`ViewExtension.azimuth` values
|
|
277
|
+
for this Collection.
|
|
278
|
+
"""
|
|
279
|
+
return self.summaries.get_range(AZIMUTH_PROP)
|
|
280
|
+
|
|
281
|
+
@azimuth.setter
|
|
282
|
+
def azimuth(self, v: RangeSummary[float] | None) -> None:
|
|
283
|
+
self._set_summary(AZIMUTH_PROP, v)
|
|
284
|
+
|
|
285
|
+
@property
|
|
286
|
+
def sun_azimuth(self) -> RangeSummary[float] | None:
|
|
287
|
+
"""Get or sets the summary of :attr:`ViewExtension.sun_azimuth` values
|
|
288
|
+
for this Collection.
|
|
289
|
+
"""
|
|
290
|
+
return self.summaries.get_range(SUN_AZIMUTH_PROP)
|
|
291
|
+
|
|
292
|
+
@sun_azimuth.setter
|
|
293
|
+
def sun_azimuth(self, v: RangeSummary[float] | None) -> None:
|
|
294
|
+
self._set_summary(SUN_AZIMUTH_PROP, v)
|
|
295
|
+
|
|
296
|
+
@property
|
|
297
|
+
def sun_elevation(self) -> RangeSummary[float] | None:
|
|
298
|
+
"""Get or sets the summary of :attr:`ViewExtension.sun_elevation` values
|
|
299
|
+
for this Collection.
|
|
300
|
+
"""
|
|
301
|
+
return self.summaries.get_range(SUN_ELEVATION_PROP)
|
|
302
|
+
|
|
303
|
+
@sun_elevation.setter
|
|
304
|
+
def sun_elevation(self, v: RangeSummary[float] | None) -> None:
|
|
305
|
+
self._set_summary(SUN_ELEVATION_PROP, v)
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
class ViewExtensionHooks(ExtensionHooks):
|
|
309
|
+
schema_uri = SCHEMA_URI
|
|
310
|
+
prev_extension_ids = {"view"}
|
|
311
|
+
stac_object_types = {pystac.STACObjectType.ITEM}
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
VIEW_EXTENSION_HOOKS: ExtensionHooks = ViewExtensionHooks()
|