parseo 0.4.4__py3-none-any.whl

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.
Files changed (70) hide show
  1. parseo/__init__.py +53 -0
  2. parseo/_epsg_lookup.py +145 -0
  3. parseo/_field_mappings.py +219 -0
  4. parseo/_json.py +14 -0
  5. parseo/_tile_systems.py +51 -0
  6. parseo/assembler.py +225 -0
  7. parseo/cli.py +383 -0
  8. parseo/parser.py +784 -0
  9. parseo/schema_registry.py +246 -0
  10. parseo/schemas/copernicus/clms/clc/clc_filename_v1_0_0.json +48 -0
  11. parseo/schemas/copernicus/clms/clc/clc_filename_v1_1_0.json +65 -0
  12. parseo/schemas/copernicus/clms/clcplus/ras/clcplus_filename_v0_0_0.json +90 -0
  13. parseo/schemas/copernicus/clms/clcplus/ras/clcplus_filename_v0_0_1.json +80 -0
  14. parseo/schemas/copernicus/clms/egms/egms_gnss_model_filename_v0_0_0.json +46 -0
  15. parseo/schemas/copernicus/clms/egms/egms_l2a_product_filename_v0_0_0.json +71 -0
  16. parseo/schemas/copernicus/clms/egms/egms_l3_velocity_grid_filename_v0_0_0.json +64 -0
  17. parseo/schemas/copernicus/clms/euhydro/euhydro_filename_v0_0_0.json +115 -0
  18. parseo/schemas/copernicus/clms/euhydro/euhydro_filename_v0_0_1.json +103 -0
  19. parseo/schemas/copernicus/clms/hr-vpp/st_filename_v0_0_0.json +82 -0
  20. parseo/schemas/copernicus/clms/hr-vpp/vi_filename_v0_0_0.json +89 -0
  21. parseo/schemas/copernicus/clms/hr-vpp/vpp_filename_v0_0_0.json +109 -0
  22. parseo/schemas/copernicus/clms/hr-wsi/cc_filename_v0_0_0.json +84 -0
  23. parseo/schemas/copernicus/clms/hr-wsi/fsc_filename_v0_0_0.json +88 -0
  24. parseo/schemas/copernicus/clms/hr-wsi/gfsc_filename_v0_0_0.json +83 -0
  25. parseo/schemas/copernicus/clms/hr-wsi/icd_filename_v0_0_0.json +96 -0
  26. parseo/schemas/copernicus/clms/hr-wsi/sp_filename_v0_0_0.json +177 -0
  27. parseo/schemas/copernicus/clms/hr-wsi/sws_filename_v0_0_0.json +83 -0
  28. parseo/schemas/copernicus/clms/hr-wsi/wcd_filename_v0_0_0.json +96 -0
  29. parseo/schemas/copernicus/clms/hr-wsi/wds_filename_v0_0_0.json +83 -0
  30. parseo/schemas/copernicus/clms/hr-wsi/wic_comb_filename_v0_0_0.json +82 -0
  31. parseo/schemas/copernicus/clms/hr-wsi/wic_filename_v0_0_0.json +90 -0
  32. parseo/schemas/copernicus/clms/hrl/fty_filename_v0_0_0.json +48 -0
  33. parseo/schemas/copernicus/clms/hrl/gra_filename_v0_0_0.json +48 -0
  34. parseo/schemas/copernicus/clms/hrl/ibu_filename_v0_0_0.json +57 -0
  35. parseo/schemas/copernicus/clms/hrl/imp_filename_v0_0_0.json +48 -0
  36. parseo/schemas/copernicus/clms/hrl/nvlcc_filename_v0_0_0.json +73 -0
  37. parseo/schemas/copernicus/clms/hrl/nvlcc_filename_v0_0_1.json +89 -0
  38. parseo/schemas/copernicus/clms/hrl/nvlcc_filename_v0_0_2.json +89 -0
  39. parseo/schemas/copernicus/clms/hrl/swf_filename_v0_0_0.json +48 -0
  40. parseo/schemas/copernicus/clms/hrl/swf_filename_v0_0_1.json +49 -0
  41. parseo/schemas/copernicus/clms/hrl/swf_filename_v0_0_2.json +93 -0
  42. parseo/schemas/copernicus/clms/hrl/swf_filename_v0_0_3.json +99 -0
  43. parseo/schemas/copernicus/clms/hrl/tcd_filename_v0_0_0.json +48 -0
  44. parseo/schemas/copernicus/clms/hrl/vlcc_filename_v0_0_0.json +105 -0
  45. parseo/schemas/copernicus/clms/hrl/waw_filename_v0_0_0.json +48 -0
  46. parseo/schemas/copernicus/clms/n2k/n2k_filename_v1_0_0.json +43 -0
  47. parseo/schemas/copernicus/clms/pa/pa_filename_v1_0_0.json +99 -0
  48. parseo/schemas/copernicus/clms/riparian-zones/rpz_filename_v0_0_0.json +50 -0
  49. parseo/schemas/copernicus/clms/urban-atlas/ua_dhm_filename_v0_0_0.json +53 -0
  50. parseo/schemas/copernicus/clms/urban-atlas/ua_filename_v0_0_0.json +105 -0
  51. parseo/schemas/copernicus/clms/urban-atlas/ua_stl_filename_v0_0_0.json +89 -0
  52. parseo/schemas/copernicus/sentinel/s1_filename_v1_0_0.json +78 -0
  53. parseo/schemas/copernicus/sentinel/s2_filename_v1_0_0.json +62 -0
  54. parseo/schemas/copernicus/sentinel/s3_filename_v1_0_0.json +22 -0
  55. parseo/schemas/copernicus/sentinel/s4_filename_v1_0_0.json +21 -0
  56. parseo/schemas/copernicus/sentinel/s5p_filename_v1_0_0.json +21 -0
  57. parseo/schemas/copernicus/sentinel/s6_filename_v1_0_0.json +23 -0
  58. parseo/schemas/eumetsat/metop_filename_v1_0_0.json +68 -0
  59. parseo/schemas/eumetsat/mtg_filename_v1_0_0.json +65 -0
  60. parseo/schemas/nasa/modis_filename_v1_0_0.json +54 -0
  61. parseo/schemas/usgs/landsat/landsat_filename_v1_0_0.json +50 -0
  62. parseo/stac_http.py +267 -0
  63. parseo/stac_scraper.py +115 -0
  64. parseo/template.py +78 -0
  65. parseo-0.4.4.dist-info/METADATA +402 -0
  66. parseo-0.4.4.dist-info/RECORD +70 -0
  67. parseo-0.4.4.dist-info/WHEEL +5 -0
  68. parseo-0.4.4.dist-info/entry_points.txt +2 -0
  69. parseo-0.4.4.dist-info/licenses/LICENSE.txt +287 -0
  70. parseo-0.4.4.dist-info/top_level.txt +1 -0
@@ -0,0 +1,246 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from dataclasses import field
5
+ from functools import lru_cache
6
+ from importlib.resources import as_file
7
+ from importlib.resources import files
8
+ from pathlib import Path
9
+ import re
10
+ from types import MappingProxyType
11
+ from typing import Any
12
+ from typing import Dict
13
+ from typing import Iterator
14
+ from typing import Mapping
15
+ from typing import Optional
16
+ from typing import Union
17
+
18
+ from ._json import load_json
19
+
20
+ SCHEMAS_ROOT = "schemas"
21
+
22
+ _FAMILY_ALIASES: Dict[str, str] = {
23
+ "IMP": "IMPERVIOUSNESS",
24
+ "SWF": "SMALL-WOODY-FEATURES",
25
+ "VI": "VEGETATION-INDEX",
26
+ }
27
+
28
+ _FAMILY_SYNONYMS: Dict[str, str] = {v: k for k, v in _FAMILY_ALIASES.items()}
29
+
30
+
31
+ def _normalize_family_name(family: str) -> str:
32
+ fam = family.upper()
33
+ if ":" in fam:
34
+ fam = fam.split(":")[-1]
35
+ return _FAMILY_SYNONYMS.get(fam, fam)
36
+
37
+
38
+ def to_display_family(family: Optional[str]) -> Optional[str]:
39
+ if family is None:
40
+ return None
41
+ return _FAMILY_ALIASES.get(family, family)
42
+
43
+
44
+ @lru_cache(maxsize=256)
45
+ def _load_json_from_path(path: Path) -> Dict:
46
+ return load_json(path)
47
+
48
+
49
+ def _iter_schema_paths(pkg: str) -> Iterator[Path]:
50
+ """Yield all schema JSON files recursively for *pkg*."""
51
+ root = files(pkg).joinpath(SCHEMAS_ROOT)
52
+ with as_file(root) as root_path:
53
+ base = Path(root_path)
54
+ if not base.exists():
55
+ return
56
+ yield from (p for p in base.rglob("*filename_v*.json") if p.is_file())
57
+
58
+
59
+ @lru_cache(maxsize=32)
60
+ def _get_schema_paths(pkg: str) -> list[Path]:
61
+ return list(_iter_schema_paths(pkg))
62
+
63
+
64
+ def _family_tokens_from_name(family: str) -> tuple[str, ...]:
65
+ fam = family.upper()
66
+ tokens = {fam}
67
+ m = re.fullmatch(r"S(\d+)([A-Z]*)", fam)
68
+ if m:
69
+ num, suffix = m.groups()
70
+ tokens.add(f"SENTINEL-{num}{suffix}")
71
+ return tuple(tokens)
72
+
73
+
74
+ @dataclass(frozen=True)
75
+ class _FamilyInfo:
76
+ """Metadata about a mission family discovered from schema files."""
77
+
78
+ schema_id: str
79
+ tokens: tuple[str, ...]
80
+ schema_path: Path
81
+ version: Optional[str] = None
82
+ status: Optional[str] = None
83
+ versions: Mapping[str, tuple[Path, Optional[str]]] = field(default_factory=dict)
84
+
85
+
86
+ @lru_cache(maxsize=1)
87
+ def _discover_family_info(pkg: str) -> Dict[str, _FamilyInfo]:
88
+ """Scan schema JSON files to discover mission families and versions."""
89
+
90
+ families: Dict[str, dict[str, Any]] = {}
91
+ for path in _get_schema_paths(pkg):
92
+ if "filename_v" not in path.name:
93
+ continue
94
+ try:
95
+ data = _load_json_from_path(path)
96
+ except (OSError, ValueError):
97
+ continue
98
+ schema_id = data.get("schema_id")
99
+ version = data.get("schema_version")
100
+ status = data.get("status", "current")
101
+ if not isinstance(schema_id, str) or not isinstance(version, str):
102
+ continue
103
+ family = schema_id.split(":")[-1].upper()
104
+ fam_entry = families.setdefault(
105
+ family,
106
+ {
107
+ "schema_id": schema_id,
108
+ "versions": {},
109
+ },
110
+ )
111
+ if not isinstance(fam_entry.get("schema_id"), str):
112
+ fam_entry["schema_id"] = schema_id
113
+ versions = fam_entry.setdefault("versions", {})
114
+ if not isinstance(versions, dict):
115
+ versions = {}
116
+ fam_entry["versions"] = versions
117
+ versions[version] = (path, status)
118
+
119
+ info: Dict[str, _FamilyInfo] = {}
120
+
121
+ for family, payload in families.items():
122
+ versions = payload.get("versions", {})
123
+ if not isinstance(versions, dict):
124
+ continue
125
+ current_version = None
126
+ current_path = None
127
+ current_status = None
128
+ for ver, (p, st) in sorted(versions.items(), reverse=True):
129
+ if st == "current":
130
+ current_version = ver
131
+ current_path = p
132
+ current_status = st
133
+ break
134
+ if current_path is None:
135
+ available = ", ".join(sorted(versions))
136
+ raise RuntimeError(
137
+ f"No schema version marked as 'current' for family {family}. "
138
+ f"Available versions: {available}"
139
+ )
140
+ schema_id = payload.get("schema_id")
141
+ if not isinstance(schema_id, str):
142
+ continue
143
+ info[family] = _FamilyInfo(
144
+ schema_id=schema_id,
145
+ tokens=_family_tokens_from_name(family),
146
+ schema_path=current_path,
147
+ version=current_version,
148
+ status=current_status,
149
+ versions=MappingProxyType(versions),
150
+ )
151
+ return info
152
+
153
+
154
+ def discover_families(pkg: str = __package__) -> Dict[str, dict]:
155
+ """Return mapping of family name to version metadata."""
156
+
157
+ info = _discover_family_info(pkg)
158
+ out: Dict[str, dict] = {}
159
+ for fam, meta in info.items():
160
+ out[fam] = {
161
+ "schema_id": meta.schema_id,
162
+ "current": meta.version,
163
+ "path": meta.schema_path,
164
+ "versions": {
165
+ ver: {"path": p, "status": st} for ver, (p, st) in meta.versions.items()
166
+ },
167
+ }
168
+ return out
169
+
170
+
171
+ def list_schema_families(pkg: str = __package__) -> list[str]:
172
+ """Return a sorted list of available mission families."""
173
+
174
+ families = discover_families(pkg)
175
+ names = set(families.keys())
176
+ for canonical in list(names):
177
+ display = to_display_family(canonical)
178
+ if display and display != canonical:
179
+ names.add(display)
180
+ return sorted(names)
181
+
182
+
183
+ def list_schema_versions(family: str, pkg: str = __package__) -> list[dict]:
184
+ """Return version descriptors for *family*."""
185
+
186
+ fam = _normalize_family_name(family)
187
+ info = discover_families(pkg)
188
+ meta = info.get(fam)
189
+ if meta is None:
190
+ raise KeyError(f"Unknown family: {family}")
191
+ versions = []
192
+ for ver, data in sorted(meta["versions"].items()):
193
+ versions.append(
194
+ {
195
+ "version": ver,
196
+ "status": data.get("status"),
197
+ "file": str(data.get("path")),
198
+ }
199
+ )
200
+ return versions
201
+
202
+
203
+ @lru_cache(maxsize=256)
204
+ def get_schema_path(
205
+ family: str, version: Union[str, None] = None, pkg: str = __package__
206
+ ) -> Path:
207
+ """Return filesystem path to schema for *family* and *version*.
208
+
209
+ If *version* is ``None`` the schema version marked as ``current`` is used.
210
+ """
211
+
212
+ fam = _normalize_family_name(family)
213
+ info = _discover_family_info(pkg)
214
+ meta = info.get(fam)
215
+ if meta is None:
216
+ raise KeyError(f"Unknown family: {family}")
217
+
218
+ if version is None:
219
+ return meta.schema_path
220
+
221
+ path_status = meta.versions.get(version)
222
+ if path_status is None:
223
+ avail = ", ".join(sorted(meta.versions))
224
+ raise KeyError(
225
+ f"Version {version!r} not found for family {family}. Available: {avail}"
226
+ )
227
+ path, _status = path_status
228
+ return path
229
+
230
+
231
+ def clear_cache() -> None:
232
+ """Clear internal caches used by the schema registry.
233
+
234
+ This helper is primarily intended for tests that need to add or modify
235
+ schema files at runtime.
236
+ """
237
+
238
+ _load_json_from_path.cache_clear()
239
+ _get_schema_paths.cache_clear()
240
+ _discover_family_info.cache_clear()
241
+ # Also clear per-schema pattern caches stored in parser module
242
+ from . import parser as _parser
243
+
244
+ _parser._SCHEMA_PATTERN_CACHE.clear()
245
+ _parser._SCHEMA_ORDER_CACHE.clear()
246
+ get_schema_path.cache_clear()
@@ -0,0 +1,48 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "schema_id": "copernicus:clms:clc",
4
+ "schema_version": "1.0.0",
5
+ "status": "deprecated",
6
+ "description": "Corine Land Cover product filename (extension optional).",
7
+ "fields": {
8
+ "project": {
9
+ "type": "string",
10
+ "enum": [
11
+ "CLC",
12
+ "U"
13
+ ],
14
+ "description": "Project code"
15
+ },
16
+ "reference_year": {
17
+ "type": "string",
18
+ "pattern": "^\\d{4}$",
19
+ "description": "Reference year (e.g., 2018, 2012)"
20
+ },
21
+ "product": {
22
+ "type": "string",
23
+ "pattern": "^[A-Z0-9]+$",
24
+ "description": "Product name, often CLCYYYY or change token"
25
+ },
26
+ "version": {
27
+ "type": "string",
28
+ "pattern": "^V\\d{4}$",
29
+ "description": "Product version (e.g., V2020)"
30
+ },
31
+ "release_number": {
32
+ "type": "string",
33
+ "pattern": "^\\d{2}(?:[A-Za-z]\\d+)?$",
34
+ "description": "Release identifier (e.g., 20, 20b2, 20u1)."
35
+ },
36
+ "extension": {
37
+ "type": "string",
38
+ "enum": [
39
+ "tif"
40
+ ],
41
+ "description": "File extension without leading dot"
42
+ }
43
+ },
44
+ "template": "{project}{reference_year}_{product}_{version}_{release_number}[.{extension}]",
45
+ "examples": [
46
+ "CLC2018_CLC2018_V2020_20u1.tif"
47
+ ]
48
+ }
@@ -0,0 +1,65 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "schema_id": "copernicus:clms:clc",
4
+ "schema_version": "1.1.0",
5
+ "status": "current",
6
+
7
+ "description": "Corine Land Cover filename (status and change layers, extension optional).",
8
+ "fields": {
9
+ "update_campaign": {
10
+ "type": "string",
11
+ "pattern": "^U\\d{4}$",
12
+ "description": "Year of the CLC update campaign (YYYY)."
13
+ },
14
+ "product": {
15
+ "type": "string",
16
+ "enum": [
17
+ "CLC",
18
+ "CHA"
19
+ ],
20
+ "description": "Layer theme: CLC for status layers, CHA for change layers."
21
+ },
22
+ "reference_code": {
23
+ "type": "string",
24
+ "pattern": "^\\d{4}$",
25
+ "description": "Reference year (status) or two-year span code (change)."
26
+ },
27
+ "change_component": {
28
+ "type": "string",
29
+ "pattern": "^(?:12|18)$",
30
+ "description": "Change raster component: 12 for consumption, 18 for formation."
31
+ },
32
+ "release_year": {
33
+ "type": "string",
34
+ "pattern": "^V\\d{4}$",
35
+ "description": "Year of data release (YYYY)."
36
+ },
37
+ "release_number": {
38
+ "type": "string",
39
+ "pattern": "^\\d{2}(?:[A-Za-z]\\d+)?$",
40
+ "description": "Release identifier (e.g., 20, 20b2, 20u1)."
41
+ },
42
+ "country_code": {
43
+ "type": "string",
44
+ "pattern": "^[A-Z]{2}$",
45
+ "description": "ISO 3166-1 alpha-2 country code for overseas deliveries."
46
+ },
47
+ "dom_code": {
48
+ "type": "string",
49
+ "pattern": "^[A-Z]{3}$",
50
+ "description": "DOM (overseas department) code used with country_code."
51
+ },
52
+ "extension": {
53
+ "type": "string",
54
+ "pattern": "^[A-Za-z0-9]+$",
55
+ "description": "File extension without leading dot."
56
+ }
57
+ },
58
+ "template": "{update_campaign}_{product}{reference_code}[_{change_component}]_{release_year}_{release_number}[_{country_code}_{dom_code}][.{extension}]",
59
+ "examples": [
60
+ "U2006_CLC2000_V2018_20b2.zip",
61
+ "U2018_CHA1218_V2020_20u1.tif",
62
+ "U2018_CHA1218_12_V2020_20u1.tif",
63
+ "U2006_CLC2000_V2018_20b2_FR_GLP.zip"
64
+ ]
65
+ }
@@ -0,0 +1,90 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "schema_id": "copernicus:clms:clcplus",
4
+ "schema_version": "0.0.0",
5
+ "status": "deprecated",
6
+ "stac_version": "1.1.0",
7
+ "stac_extensions": [
8
+ "https://stac-extensions.github.io/raster/v1.0.0/schema.json",
9
+ "https://stac-extensions.github.io/eo/v1.0.0/schema.json"
10
+ ],
11
+ "description": "CLMS CLC+ raster product filename (extension optional).",
12
+ "fields": {
13
+ "programme": {
14
+ "type": "string",
15
+ "enum": [
16
+ "CLMS"
17
+ ],
18
+ "description": "Copernicus Land Monitoring Service programme identifier"
19
+ },
20
+ "product": {
21
+ "type": "string",
22
+ "enum": [
23
+ "CLCPLUS"
24
+ ],
25
+ "description": "Product family identifier"
26
+ },
27
+ "type": {
28
+ "type": "string",
29
+ "enum": [
30
+ "RASTER"
31
+ ],
32
+ "description": "Data class code (raster)",
33
+ "stac_map": {
34
+ "values": {
35
+ "RAS": {
36
+ "type": "raster"
37
+ }
38
+ }
39
+ }
40
+ },
41
+ "season": {
42
+ "type": "string",
43
+ "pattern": "^(\\d{4}|C\\d{4}-\\d{4})$",
44
+ "description": "Reference season and year (SYYYY) or change interval (CYYYY-YYYY)"
45
+ },
46
+ "resolution": {
47
+ "type": "string",
48
+ "pattern": "^\\d{3}m$",
49
+ "description": "Spatial resolution expressed with leading 'R' and units"
50
+ },
51
+ "tile_id": {
52
+ "description": "Tile identifier in the EEA 10m grid (easting/northing) or two-letter geographic code",
53
+ "oneOf": [
54
+ {
55
+ "title": "INSPIRE ETRS89-LAEA Grid",
56
+ "type": "string",
57
+ "pattern": "^[EW]\\d{2,3}[NS]\\d{2,3}$",
58
+ "description": "Regional LAEA grid tile identifier (2- or 3-digit coordinates)"
59
+ },
60
+ {
61
+ "title": "Geographic code",
62
+ "type": "string",
63
+ "pattern": "^[A-Z]{2}$",
64
+ "description": "Two-letter geographic code used by VLCC vector products"
65
+ }
66
+ ]
67
+ },
68
+ "epsg_code": {
69
+ "type": "string",
70
+ "pattern": "^0?\\d{4}$",
71
+ "description": "EPSG code of the product grid"
72
+ },
73
+ "version": {
74
+ "type": "string",
75
+ "pattern": "^V\\d{1}_\\d{1}$",
76
+ "description": "Product version"
77
+ },
78
+ "extension": {
79
+ "type": "string",
80
+ "enum": [
81
+ "tif"
82
+ ],
83
+ "description": "File extension without leading dot"
84
+ }
85
+ },
86
+ "template": "{programme}_{product}_{type}_{season}_{resolution}_{tile_id}_{epsg_code}_{version}[.{extension}]",
87
+ "examples": [
88
+ "CLMS_CLCPLUS_RASTER_2018_010m_E48N37_03035_V1_1.tif"
89
+ ]
90
+ }
@@ -0,0 +1,80 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "schema_id": "copernicus:clms:clcplus",
4
+ "schema_version": "0.0.1",
5
+ "status": "current",
6
+ "stac_version": "1.1.0",
7
+ "description": "CLMS CLC+ raster product filename (extension optional).",
8
+ "fields": {
9
+ "programme": {
10
+ "type": "string",
11
+ "enum": [
12
+ "CLMS"
13
+ ],
14
+ "description": "Copernicus Land Monitoring Service programme identifier"
15
+ },
16
+ "product": {
17
+ "type": "string",
18
+ "enum": [
19
+ "CLCPLUS"
20
+ ],
21
+ "description": "Product family identifier"
22
+ },
23
+ "type": {
24
+ "type": "string",
25
+ "enum": [
26
+ "RAS"
27
+ ],
28
+ "description": "Data class code (raster)",
29
+ "stac_map": {
30
+ "values": {
31
+ "RAS": {
32
+ "representation": "raster"
33
+ }
34
+ }
35
+ }
36
+ },
37
+ "season": {
38
+ "type": "string",
39
+ "pattern": "^(S\\d{4}|C\\d{4}-\\d{4})$",
40
+ "description": "Reference season and year (SYYYY) or change interval (CYYYY-YYYY)"
41
+ },
42
+ "resolution": {
43
+ "type": "string",
44
+ "pattern": "^R\\d{2}m$",
45
+ "description": "Spatial resolution expressed with leading 'R' and units"
46
+ },
47
+ "tile_id": {
48
+ "title": "INSPIRE ETRS89-LAEA Grid",
49
+ "type": "string",
50
+ "pattern": "^[EW]\\d{2,3}[NS]\\d{2,3}$",
51
+ "description": "Regional LAEA grid tile identifier (2- or 3-digit coordinates)"
52
+ },
53
+ "epsg_code": {
54
+ "type": "string",
55
+ "pattern": "^0?\\d{4}$",
56
+ "description": "EPSG code of the product grid"
57
+ },
58
+ "version": {
59
+ "type": "string",
60
+ "pattern": "^V\\d{2}$",
61
+ "description": "Product version"
62
+ },
63
+ "revision": {
64
+ "type": "string",
65
+ "pattern": "^R\\d{2}$",
66
+ "description": "Product revision"
67
+ },
68
+ "extension": {
69
+ "type": "string",
70
+ "enum": [
71
+ "tif"
72
+ ],
73
+ "description": "File extension without leading dot"
74
+ }
75
+ },
76
+ "template": "{programme}_{product}_{type}_{season}_{resolution}_{tile_id}_{epsg_code}_{version}_{revision}[.{extension}]",
77
+ "examples": [
78
+ "CLMS_CLCPLUS_RAS_S2023_R10m_E48N37_03035_V01_R00.tif"
79
+ ]
80
+ }
@@ -0,0 +1,46 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "schema_id": "copernicus:clms:egms-gnss-model",
4
+ "schema_version": "0.0.0",
5
+ "status": "current",
6
+
7
+ "description": "Copernicus European Ground Motion Service GNSS model filename.",
8
+ "fields": {
9
+ "product": {
10
+ "type": "string",
11
+ "enum": [
12
+ "EGMS"
13
+ ],
14
+ "description": "Constant service prefix"
15
+ },
16
+ "variable": {
17
+ "type": "string",
18
+ "enum": [
19
+ "AEPND"
20
+ ],
21
+ "description": "Product identifier"
22
+ },
23
+ "issue_year": {
24
+ "type": "string",
25
+ "pattern": "^V\\d{4}$",
26
+ "description": "Year of issue"
27
+ },
28
+ "revision": {
29
+ "type": "string",
30
+ "pattern": "^\\d$",
31
+ "description": "Revision within the year (0 pre-release, 1 first full release)"
32
+ },
33
+ "extension": {
34
+ "type": "string",
35
+ "enum": [
36
+ "csv"
37
+ ],
38
+ "description": "File extension without leading dot"
39
+ }
40
+ },
41
+ "template": "{product}_{variable}_{issue_year}.{revision}.{extension}",
42
+ "examples": [
43
+ "EGMS_AEPND_V2020.0.csv",
44
+ "EGMS_AEPND_V2023.1.csv"
45
+ ]
46
+ }
@@ -0,0 +1,71 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "schema_id": "copernicus:clms:egms-l2a",
4
+ "schema_version": "0.0.0",
5
+ "status": "current",
6
+
7
+ "description": "Copernicus European Ground Motion Service Level 2 basic and calibrated product filename (extension optional).",
8
+ "fields": {
9
+ "product": {
10
+ "type": "string",
11
+ "enum": [
12
+ "EGMS"
13
+ ],
14
+ "description": "Constant service prefix"
15
+ },
16
+ "level": {
17
+ "type": "string",
18
+ "pattern": "^L[0-9]+[a-zA-Z]$",
19
+ "description": "Product processing level"
20
+ },
21
+ "track": {
22
+ "type": "string",
23
+ "pattern": "^\\d{3}$",
24
+ "description": "Sentinel-1 track number"
25
+ },
26
+ "burst": {
27
+ "type": "string",
28
+ "pattern": "^\\d{4}$",
29
+ "description": "Progressive index of the burst inside the track"
30
+ },
31
+ "swath": {
32
+ "type": "string",
33
+ "pattern": "^IW[0-9]$",
34
+ "description": "Sentinel-1 IW swath identifier"
35
+ },
36
+ "polarisation": {
37
+ "type": "string",
38
+ "pattern": "^(?:VV|VH|HH|HV)$",
39
+ "description": "Polarisation of the SAR acquisition"
40
+ },
41
+ "start_year": {
42
+ "type": "string",
43
+ "pattern": "^\\d{4}$",
44
+ "description": "First nominal year included in the product"
45
+ },
46
+ "end_year": {
47
+ "type": "string",
48
+ "pattern": "^\\d{4}$",
49
+ "description": "Last nominal year included in the product"
50
+ },
51
+ "version": {
52
+ "type": "string",
53
+ "pattern": "^\\d+$",
54
+ "description": "Version of the delivered data"
55
+ },
56
+ "extension": {
57
+ "type": "string",
58
+ "enum": [
59
+ "csv",
60
+ "zip"
61
+ ],
62
+ "description": "File extension without leading dot"
63
+ }
64
+ },
65
+ "template": "{product}_{level}_{track}_{burst}_{swath}_{polarisation}_{start_year}_{end_year}_{version}[.{extension}]",
66
+ "examples": [
67
+ "EGMS_L2a_088_0282_IW2_VV_2018_2022_1.csv",
68
+ "EGMS_L2a_088_0282_IW2_VV_2018_2022_1.zip",
69
+ "EGMS_L2a_124_0135_IW1_VH_2015_2020_2.csv"
70
+ ]
71
+ }