pystac-ext-sat 1.0.0__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_sat-1.0.0/.gitignore +163 -0
- pystac_ext_sat-1.0.0/PKG-INFO +37 -0
- pystac_ext_sat-1.0.0/README.md +13 -0
- pystac_ext_sat-1.0.0/pyproject.toml +36 -0
- pystac_ext_sat-1.0.0/pystac/extensions/py.typed +0 -0
- pystac_ext_sat-1.0.0/pystac/extensions/sat.py +319 -0
- pystac_ext_sat-1.0.0/tests/cassettes/test_sat/test_absolute_orbit.yaml +62 -0
- pystac_ext_sat-1.0.0/tests/cassettes/test_sat/test_anx_datetime.yaml +62 -0
- pystac_ext_sat-1.0.0/tests/cassettes/test_sat/test_both.yaml +62 -0
- pystac_ext_sat-1.0.0/tests/cassettes/test_sat/test_clear_orbit_state.yaml +62 -0
- pystac_ext_sat-1.0.0/tests/cassettes/test_sat/test_clear_relative_orbit.yaml +62 -0
- pystac_ext_sat-1.0.0/tests/cassettes/test_sat/test_modify.yaml +62 -0
- pystac_ext_sat-1.0.0/tests/cassettes/test_sat/test_no_args_fails.yaml +62 -0
- pystac_ext_sat-1.0.0/tests/cassettes/test_sat/test_orbit_state.yaml +62 -0
- pystac_ext_sat-1.0.0/tests/cassettes/test_sat/test_platform_international_designator.yaml +62 -0
- pystac_ext_sat-1.0.0/tests/cassettes/test_sat/test_relative_orbit.yaml +62 -0
- pystac_ext_sat-1.0.0/tests/cassettes/test_sat/test_relative_orbit_no_negative.yaml +62 -0
- pystac_ext_sat-1.0.0/tests/data-files/collections/multi-extent.json +66 -0
- pystac_ext_sat-1.0.0/tests/data-files/sentinel-1.json +126 -0
- pystac_ext_sat-1.0.0/tests/test_sat.py +350 -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-sat
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Satellite 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,sat
|
|
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-sat
|
|
26
|
+
|
|
27
|
+
[PySTAC](https://pypi.org/project/pystac/) extension package for the [Satellite Extension](https://github.com/stac-extensions/sat).
|
|
28
|
+
This extension provides fields for describing satellite-specific metadata, including orbit state vectors, relative orbit numbers, and platform-specific identifiers.
|
|
29
|
+
|
|
30
|
+
## Supported versions
|
|
31
|
+
|
|
32
|
+
- [v1.0.0](https://stac-extensions.github.io/sat/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-sat
|
|
2
|
+
|
|
3
|
+
[PySTAC](https://pypi.org/project/pystac/) extension package for the [Satellite Extension](https://github.com/stac-extensions/sat).
|
|
4
|
+
This extension provides fields for describing satellite-specific metadata, including orbit state vectors, relative orbit numbers, and platform-specific identifiers.
|
|
5
|
+
|
|
6
|
+
## Supported versions
|
|
7
|
+
|
|
8
|
+
- [v1.0.0](https://stac-extensions.github.io/sat/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-sat"
|
|
3
|
+
description = "Satellite extension for PySTAC"
|
|
4
|
+
readme = "README.md"
|
|
5
|
+
version = "1.0.0"
|
|
6
|
+
authors = []
|
|
7
|
+
maintainers = []
|
|
8
|
+
keywords = ["pystac", "imagery", "raster", "catalog", "STAC", "sat"]
|
|
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,319 @@
|
|
|
1
|
+
"""Implements the :stac-ext:`Satellite Extension <sat>`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Iterable
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from typing import (
|
|
8
|
+
Any,
|
|
9
|
+
Generic,
|
|
10
|
+
Literal,
|
|
11
|
+
TypeVar,
|
|
12
|
+
cast,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
import pystac
|
|
16
|
+
from pystac.extensions.base import (
|
|
17
|
+
ExtensionManagementMixin,
|
|
18
|
+
PropertiesExtension,
|
|
19
|
+
SummariesExtension,
|
|
20
|
+
)
|
|
21
|
+
from pystac.extensions.hooks import ExtensionHooks
|
|
22
|
+
from pystac.summaries import RangeSummary
|
|
23
|
+
from pystac.utils import StringEnum, datetime_to_str, map_opt, str_to_datetime
|
|
24
|
+
|
|
25
|
+
#: Generalized version of :class:`~pystac.Item`, :class:`~pystac.Asset` or
|
|
26
|
+
#: :class:`~pystac.ItemAssetDefinition`
|
|
27
|
+
T = TypeVar("T", pystac.Item, pystac.Asset, pystac.ItemAssetDefinition)
|
|
28
|
+
|
|
29
|
+
SCHEMA_URI = "https://stac-extensions.github.io/sat/v1.0.0/schema.json"
|
|
30
|
+
|
|
31
|
+
PREFIX: str = "sat:"
|
|
32
|
+
PLATFORM_INTERNATIONAL_DESIGNATOR_PROP: str = (
|
|
33
|
+
PREFIX + "platform_international_designator"
|
|
34
|
+
)
|
|
35
|
+
ABSOLUTE_ORBIT_PROP: str = PREFIX + "absolute_orbit"
|
|
36
|
+
ORBIT_STATE_PROP: str = PREFIX + "orbit_state"
|
|
37
|
+
RELATIVE_ORBIT_PROP: str = PREFIX + "relative_orbit"
|
|
38
|
+
ANX_DATETIME_PROP: str = PREFIX + "anx_datetime"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class OrbitState(StringEnum):
|
|
42
|
+
ASCENDING = "ascending"
|
|
43
|
+
DESCENDING = "descending"
|
|
44
|
+
GEOSTATIONARY = "geostationary"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class SatExtension(
|
|
48
|
+
Generic[T],
|
|
49
|
+
PropertiesExtension,
|
|
50
|
+
ExtensionManagementMixin[pystac.Item | pystac.Collection],
|
|
51
|
+
):
|
|
52
|
+
"""An abstract class that can be used to extend the properties of an
|
|
53
|
+
:class:`~pystac.Item` or :class:`~pystac.Asset` with properties from the
|
|
54
|
+
:stac-ext:`Satellite Extension <sat>`. This class is generic over the type of
|
|
55
|
+
STAC Object to be extended (e.g. :class:`~pystac.Item`,
|
|
56
|
+
:class:`~pystac.Collection`).
|
|
57
|
+
|
|
58
|
+
To create a concrete instance of :class:`SatExtension`, use the
|
|
59
|
+
:meth:`SatExtension.ext` method. For example:
|
|
60
|
+
|
|
61
|
+
.. code-block:: python
|
|
62
|
+
|
|
63
|
+
>>> item: pystac.Item = ...
|
|
64
|
+
>>> sat_ext = SatExtension.ext(item)
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
name: Literal["sat"] = "sat"
|
|
68
|
+
|
|
69
|
+
def apply(
|
|
70
|
+
self,
|
|
71
|
+
orbit_state: OrbitState | None = None,
|
|
72
|
+
relative_orbit: int | None = None,
|
|
73
|
+
absolute_orbit: int | None = None,
|
|
74
|
+
platform_international_designator: str | None = None,
|
|
75
|
+
anx_datetime: datetime | None = None,
|
|
76
|
+
) -> None:
|
|
77
|
+
"""Applies ext extension properties to the extended :class:`~pystac.Item` or
|
|
78
|
+
class:`~pystac.Asset`.
|
|
79
|
+
|
|
80
|
+
Must specify at least one of orbit_state or relative_orbit in order
|
|
81
|
+
for the sat extension to properties to be valid.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
orbit_state : Optional state of the orbit. Either ascending or
|
|
85
|
+
descending for polar orbiting satellites, or geostationary for
|
|
86
|
+
geosynchronous satellites.
|
|
87
|
+
relative_orbit : Optional non-negative integer of the orbit number at
|
|
88
|
+
the time of acquisition.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
self.platform_international_designator = platform_international_designator
|
|
92
|
+
self.orbit_state = orbit_state
|
|
93
|
+
self.absolute_orbit = absolute_orbit
|
|
94
|
+
self.relative_orbit = relative_orbit
|
|
95
|
+
self.anx_datetime = anx_datetime
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def platform_international_designator(self) -> str | None:
|
|
99
|
+
"""Gets or sets the International Designator, also known as COSPAR ID, and
|
|
100
|
+
NSSDCA ID."""
|
|
101
|
+
return self._get_property(PLATFORM_INTERNATIONAL_DESIGNATOR_PROP, str)
|
|
102
|
+
|
|
103
|
+
@platform_international_designator.setter
|
|
104
|
+
def platform_international_designator(self, v: str | None) -> None:
|
|
105
|
+
self._set_property(PLATFORM_INTERNATIONAL_DESIGNATOR_PROP, v)
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def orbit_state(self) -> OrbitState | None:
|
|
109
|
+
"""Get or sets an orbit state of the object."""
|
|
110
|
+
return map_opt(
|
|
111
|
+
lambda x: OrbitState(x), self._get_property(ORBIT_STATE_PROP, str)
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
@orbit_state.setter
|
|
115
|
+
def orbit_state(self, v: OrbitState | None) -> None:
|
|
116
|
+
self._set_property(ORBIT_STATE_PROP, map_opt(lambda x: x.value, v))
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def absolute_orbit(self) -> int | None:
|
|
120
|
+
"""Get or sets an absolute orbit number of the item."""
|
|
121
|
+
return self._get_property(ABSOLUTE_ORBIT_PROP, int)
|
|
122
|
+
|
|
123
|
+
@absolute_orbit.setter
|
|
124
|
+
def absolute_orbit(self, v: int | None) -> None:
|
|
125
|
+
self._set_property(ABSOLUTE_ORBIT_PROP, v)
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def relative_orbit(self) -> int | None:
|
|
129
|
+
"""Get or sets a relative orbit number of the item."""
|
|
130
|
+
return self._get_property(RELATIVE_ORBIT_PROP, int)
|
|
131
|
+
|
|
132
|
+
@relative_orbit.setter
|
|
133
|
+
def relative_orbit(self, v: int | None) -> None:
|
|
134
|
+
self._set_property(RELATIVE_ORBIT_PROP, v)
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def anx_datetime(self) -> datetime | None:
|
|
138
|
+
return map_opt(str_to_datetime, self._get_property(ANX_DATETIME_PROP, str))
|
|
139
|
+
|
|
140
|
+
@anx_datetime.setter
|
|
141
|
+
def anx_datetime(self, v: datetime | None) -> None:
|
|
142
|
+
self._set_property(ANX_DATETIME_PROP, map_opt(datetime_to_str, v))
|
|
143
|
+
|
|
144
|
+
@classmethod
|
|
145
|
+
def get_schema_uri(cls) -> str:
|
|
146
|
+
return SCHEMA_URI
|
|
147
|
+
|
|
148
|
+
@classmethod
|
|
149
|
+
def ext(cls, obj: T, add_if_missing: bool = False) -> SatExtension[T]:
|
|
150
|
+
"""Extends the given STAC Object with properties from the :stac-ext:`Satellite
|
|
151
|
+
Extension <sat>`.
|
|
152
|
+
|
|
153
|
+
This extension can be applied to instances of :class:`~pystac.Item` or
|
|
154
|
+
:class:`~pystac.Asset`.
|
|
155
|
+
|
|
156
|
+
Raises:
|
|
157
|
+
|
|
158
|
+
pystac.ExtensionTypeError : If an invalid object type is passed.
|
|
159
|
+
"""
|
|
160
|
+
if isinstance(obj, pystac.Item):
|
|
161
|
+
cls.ensure_has_extension(obj, add_if_missing)
|
|
162
|
+
return cast(SatExtension[T], ItemSatExtension(obj))
|
|
163
|
+
elif isinstance(obj, pystac.Asset):
|
|
164
|
+
cls.ensure_owner_has_extension(obj, add_if_missing)
|
|
165
|
+
return cast(SatExtension[T], AssetSatExtension(obj))
|
|
166
|
+
elif isinstance(obj, pystac.ItemAssetDefinition):
|
|
167
|
+
cls.ensure_owner_has_extension(obj, add_if_missing)
|
|
168
|
+
return cast(SatExtension[T], ItemAssetsSatExtension(obj))
|
|
169
|
+
else:
|
|
170
|
+
raise pystac.ExtensionTypeError(cls._ext_error_message(obj))
|
|
171
|
+
|
|
172
|
+
@classmethod
|
|
173
|
+
def summaries(
|
|
174
|
+
cls, obj: pystac.Collection, add_if_missing: bool = False
|
|
175
|
+
) -> SummariesSatExtension:
|
|
176
|
+
"""Returns the extended summaries object for the given collection."""
|
|
177
|
+
cls.ensure_has_extension(obj, add_if_missing)
|
|
178
|
+
return SummariesSatExtension(obj)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class ItemSatExtension(SatExtension[pystac.Item]):
|
|
182
|
+
"""A concrete implementation of :class:`SatExtension` on an :class:`~pystac.Item`
|
|
183
|
+
that extends the properties of the Item to include properties defined in the
|
|
184
|
+
:stac-ext:`Satellite Extension <sat>`.
|
|
185
|
+
|
|
186
|
+
This class should generally not be instantiated directly. Instead, call
|
|
187
|
+
:meth:`SatExtension.ext` on an :class:`~pystac.Item` to
|
|
188
|
+
extend it.
|
|
189
|
+
"""
|
|
190
|
+
|
|
191
|
+
item: pystac.Item
|
|
192
|
+
"""The :class:`~pystac.Item` being extended."""
|
|
193
|
+
|
|
194
|
+
properties: dict[str, Any]
|
|
195
|
+
"""The :class:`~pystac.Item` properties, including extension properties."""
|
|
196
|
+
|
|
197
|
+
def __init__(self, item: pystac.Item):
|
|
198
|
+
self.item = item
|
|
199
|
+
self.properties = item.properties
|
|
200
|
+
|
|
201
|
+
def __repr__(self) -> str:
|
|
202
|
+
return f"<ItemSatExtension Item id={self.item.id}>"
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class AssetSatExtension(SatExtension[pystac.Asset]):
|
|
206
|
+
"""A concrete implementation of :class:`SatExtension` on an :class:`~pystac.Asset`
|
|
207
|
+
that extends the properties of the Asset to include properties defined in the
|
|
208
|
+
:stac-ext:`Satellite Extension <sat>`.
|
|
209
|
+
|
|
210
|
+
This class should generally not be instantiated directly. Instead, call
|
|
211
|
+
:meth:`SatExtension.ext` on an :class:`~pystac.Asset` to
|
|
212
|
+
extend it.
|
|
213
|
+
"""
|
|
214
|
+
|
|
215
|
+
asset_href: str
|
|
216
|
+
"""The ``href`` value of the :class:`~pystac.Asset` being extended."""
|
|
217
|
+
|
|
218
|
+
properties: dict[str, Any]
|
|
219
|
+
"""The :class:`~pystac.Asset` fields, including extension properties."""
|
|
220
|
+
|
|
221
|
+
additional_read_properties: Iterable[dict[str, Any]] | None = None
|
|
222
|
+
"""If present, this will be a list containing 1 dictionary representing the
|
|
223
|
+
properties of the owning :class:`~pystac.Item`."""
|
|
224
|
+
|
|
225
|
+
def __init__(self, asset: pystac.Asset):
|
|
226
|
+
self.asset_href = asset.href
|
|
227
|
+
self.properties = asset.extra_fields
|
|
228
|
+
if asset.owner and isinstance(asset.owner, pystac.Item):
|
|
229
|
+
self.additional_read_properties = [asset.owner.properties]
|
|
230
|
+
|
|
231
|
+
def __repr__(self) -> str:
|
|
232
|
+
return f"<AssetSatExtension Asset href={self.asset_href}>"
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
class ItemAssetsSatExtension(SatExtension[pystac.ItemAssetDefinition]):
|
|
236
|
+
properties: dict[str, Any]
|
|
237
|
+
asset_defn: pystac.ItemAssetDefinition
|
|
238
|
+
|
|
239
|
+
def __init__(self, item_asset: pystac.ItemAssetDefinition):
|
|
240
|
+
self.asset_defn = item_asset
|
|
241
|
+
self.properties = item_asset.properties
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
class SummariesSatExtension(SummariesExtension):
|
|
245
|
+
"""A concrete implementation of :class:`~pystac.extensions.base.SummariesExtension`
|
|
246
|
+
that extends the ``summaries`` field of a :class:`~pystac.Collection` to include
|
|
247
|
+
properties defined in the :stac-ext:`Satellite Extension <sat>`.
|
|
248
|
+
"""
|
|
249
|
+
|
|
250
|
+
@property
|
|
251
|
+
def platform_international_designator(self) -> list[str] | None:
|
|
252
|
+
"""Get or sets the summary of
|
|
253
|
+
:attr:`SatExtension.platform_international_designator` values for this
|
|
254
|
+
Collection.
|
|
255
|
+
"""
|
|
256
|
+
|
|
257
|
+
return self.summaries.get_list(PLATFORM_INTERNATIONAL_DESIGNATOR_PROP)
|
|
258
|
+
|
|
259
|
+
@platform_international_designator.setter
|
|
260
|
+
def platform_international_designator(self, v: list[str] | None) -> None:
|
|
261
|
+
self._set_summary(PLATFORM_INTERNATIONAL_DESIGNATOR_PROP, v)
|
|
262
|
+
|
|
263
|
+
@property
|
|
264
|
+
def orbit_state(self) -> list[OrbitState] | None:
|
|
265
|
+
"""Get or sets the summary of :attr:`SatExtension.orbit_state` values
|
|
266
|
+
for this Collection.
|
|
267
|
+
"""
|
|
268
|
+
|
|
269
|
+
return self.summaries.get_list(ORBIT_STATE_PROP)
|
|
270
|
+
|
|
271
|
+
@orbit_state.setter
|
|
272
|
+
def orbit_state(self, v: list[OrbitState] | None) -> None:
|
|
273
|
+
self._set_summary(ORBIT_STATE_PROP, v)
|
|
274
|
+
|
|
275
|
+
@property
|
|
276
|
+
def absolute_orbit(self) -> RangeSummary[int] | None:
|
|
277
|
+
return self.summaries.get_range(ABSOLUTE_ORBIT_PROP)
|
|
278
|
+
|
|
279
|
+
@absolute_orbit.setter
|
|
280
|
+
def absolute_orbit(self, v: RangeSummary[int] | None) -> None:
|
|
281
|
+
self._set_summary(ABSOLUTE_ORBIT_PROP, v)
|
|
282
|
+
|
|
283
|
+
@property
|
|
284
|
+
def relative_orbit(self) -> RangeSummary[int] | None:
|
|
285
|
+
return self.summaries.get_range(RELATIVE_ORBIT_PROP)
|
|
286
|
+
|
|
287
|
+
@relative_orbit.setter
|
|
288
|
+
def relative_orbit(self, v: RangeSummary[int] | None) -> None:
|
|
289
|
+
self._set_summary(RELATIVE_ORBIT_PROP, v)
|
|
290
|
+
|
|
291
|
+
@property
|
|
292
|
+
def anx_datetime(self) -> RangeSummary[datetime] | None:
|
|
293
|
+
return map_opt(
|
|
294
|
+
lambda s: RangeSummary(
|
|
295
|
+
str_to_datetime(s.minimum), str_to_datetime(s.maximum)
|
|
296
|
+
),
|
|
297
|
+
self.summaries.get_range(ANX_DATETIME_PROP),
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
@anx_datetime.setter
|
|
301
|
+
def anx_datetime(self, v: RangeSummary[datetime] | None) -> None:
|
|
302
|
+
self._set_summary(
|
|
303
|
+
ANX_DATETIME_PROP,
|
|
304
|
+
map_opt(
|
|
305
|
+
lambda s: RangeSummary(
|
|
306
|
+
datetime_to_str(s.minimum), datetime_to_str(s.maximum)
|
|
307
|
+
),
|
|
308
|
+
v,
|
|
309
|
+
),
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
class SatExtensionHooks(ExtensionHooks):
|
|
314
|
+
schema_uri: str = SCHEMA_URI
|
|
315
|
+
prev_extension_ids = {"sat"}
|
|
316
|
+
stac_object_types = {pystac.STACObjectType.ITEM}
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
SAT_EXTENSION_HOOKS: ExtensionHooks = SatExtensionHooks()
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
interactions:
|
|
2
|
+
- request:
|
|
3
|
+
body: null
|
|
4
|
+
headers: {}
|
|
5
|
+
method: GET
|
|
6
|
+
uri: https://stac-extensions.github.io/sat/v1.0.0/schema.json
|
|
7
|
+
response:
|
|
8
|
+
body:
|
|
9
|
+
string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\":
|
|
10
|
+
\"https://stac-extensions.github.io/sat/v1.0.0/schema.json\",\n \"title\":
|
|
11
|
+
\"Satellite Extension\",\n \"description\": \"STAC Sat Extension to a STAC
|
|
12
|
+
Item.\",\n \"oneOf\": [\n {\n \"$comment\": \"This is the schema
|
|
13
|
+
for STAC Items.\",\n \"allOf\": [\n {\n \"type\": \"object\",\n
|
|
14
|
+
\ \"required\": [\n \"type\",\n \"properties\",\n
|
|
15
|
+
\ \"assets\"\n ],\n \"properties\": {\n \"type\":
|
|
16
|
+
{\n \"const\": \"Feature\"\n },\n \"properties\":
|
|
17
|
+
{\n \"allOf\": [\n {\n \"anyOf\":
|
|
18
|
+
[\n {\n \"required\": [\n \"sat:platform_international_designator\"\n
|
|
19
|
+
\ ]\n },\n {\n \"required\":
|
|
20
|
+
[\n \"sat:orbit_state\"\n ]\n
|
|
21
|
+
\ },\n {\n \"required\":
|
|
22
|
+
[\n \"sat:absolute_orbit\"\n ]\n
|
|
23
|
+
\ },\n {\n \"required\":
|
|
24
|
+
[\n \"sat:relative_orbit\"\n ]\n
|
|
25
|
+
\ },\n {\n \"required\":
|
|
26
|
+
[\n \"sat:anx_datetime\"\n ]\n
|
|
27
|
+
\ }\n ]\n },\n {\n
|
|
28
|
+
\ \"$ref\": \"#/definitions/fields\"\n }\n
|
|
29
|
+
\ ]\n },\n \"assets\": {\n \"type\":
|
|
30
|
+
\"object\",\n \"additionalProperties\": {\n \"$ref\":
|
|
31
|
+
\"#/definitions/fields\"\n }\n }\n }\n },\n
|
|
32
|
+
\ {\n \"$ref\": \"#/definitions/stac_extensions\"\n }\n
|
|
33
|
+
\ ]\n },\n {\n \"$comment\": \"This is the schema for STAC
|
|
34
|
+
Collections.\",\n \"allOf\": [\n {\n \"type\": \"object\",\n
|
|
35
|
+
\ \"required\": [\n \"type\"\n ],\n \"properties\":
|
|
36
|
+
{\n \"type\": {\n \"const\": \"Collection\"\n },\n
|
|
37
|
+
\ \"assets\": {\n \"type\": \"object\",\n \"additionalProperties\":
|
|
38
|
+
{\n \"$ref\": \"#/definitions/fields\"\n }\n },\n
|
|
39
|
+
\ \"item_assets\": {\n \"type\": \"object\",\n \"additionalProperties\":
|
|
40
|
+
{\n \"$ref\": \"#/definitions/fields\"\n }\n }\n
|
|
41
|
+
\ }\n }\n ]\n }\n ],\n \"definitions\": {\n \"stac_extensions\":
|
|
42
|
+
{\n \"type\": \"object\",\n \"required\": [\n \"stac_extensions\"\n
|
|
43
|
+
\ ],\n \"properties\": {\n \"stac_extensions\": {\n \"type\":
|
|
44
|
+
\"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/sat/v1.0.0/schema.json\"\n
|
|
45
|
+
\ }\n }\n }\n },\n \"fields\": {\n \"type\":
|
|
46
|
+
\"object\",\n \"properties\": {\n \"sat:platform_international_designator\":
|
|
47
|
+
{\n \"type\": \"string\"\n },\n \"sat:orbit_state\":
|
|
48
|
+
{\n \"title\": \"Orbit State\",\n \"type\": \"string\",\n
|
|
49
|
+
\ \"enum\": [\n \"ascending\",\n \"descending\",\n
|
|
50
|
+
\ \"geostationary\"\n ]\n },\n \"sat:absolute_orbit\":
|
|
51
|
+
{\n \"type\": \"integer\",\n \"minimum\": 1\n },\n
|
|
52
|
+
\ \"sat:relative_orbit\": {\n \"type\": \"integer\",\n \"minimum\":
|
|
53
|
+
1\n },\n \"sat:anx_datetime\": {\n \"type\": \"string\",\n
|
|
54
|
+
\ \"format\": \"date-time\"\n }\n },\n \"patternProperties\":
|
|
55
|
+
{\n \"^(?!sat:)\": {\n \"$comment\": \"Do not allow unspecified
|
|
56
|
+
fields prefixed with sat:\"\n }\n },\n \"additionalProperties\":
|
|
57
|
+
false\n }\n }\n}"
|
|
58
|
+
headers: {}
|
|
59
|
+
status:
|
|
60
|
+
code: 200
|
|
61
|
+
message: OK
|
|
62
|
+
version: 1
|