simplestac 2.0.0__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.
- simplestac/__init__.py +7 -0
- simplestac/extents.py +223 -0
- simplestac/formats/S1_GRD.json +60 -0
- simplestac/formats/S1_RTC_GEODES.json +55 -0
- simplestac/formats/S2_L2A_THEIA.json +166 -0
- simplestac/formats/common_name_table.csv +17 -0
- simplestac/local.py +496 -0
- simplestac/raster.py +360 -0
- simplestac/search.py +398 -0
- simplestac/types.py +2 -0
- simplestac/utils.py +1692 -0
- simplestac-2.0.0.dist-info/METADATA +235 -0
- simplestac-2.0.0.dist-info/RECORD +16 -0
- simplestac-2.0.0.dist-info/WHEEL +5 -0
- simplestac-2.0.0.dist-info/licenses/LICENSE +661 -0
- simplestac-2.0.0.dist-info/top_level.txt +1 -0
simplestac/__init__.py
ADDED
simplestac/extents.py
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Deal with STAC Extents.
|
|
3
|
+
|
|
4
|
+
# AutoSpatialExtent
|
|
5
|
+
|
|
6
|
+
The vanilla `pystac.SpatialExtent` enables to describe a spatial extent
|
|
7
|
+
from several bounding boxes. While this is useful, sometimes we want to
|
|
8
|
+
merge together bounding boxes that are partially overlapping. For instance,
|
|
9
|
+
we can take the example of the France mainland, covered by multiple remote
|
|
10
|
+
sensing products that are generally partially overlapping, and the Corse
|
|
11
|
+
island that is also covered by a number of RS products, but spatially
|
|
12
|
+
disjoint from the France mainland RS products bounding boxes. In this
|
|
13
|
+
particular exemple, we would like to regroup all RS products bounding
|
|
14
|
+
boxes so that there is one bbox for the France mainland, and another
|
|
15
|
+
bbox for the Corse island. This is particularly useful when a STAC
|
|
16
|
+
collection covers sparsely a broad area (e.g. worldwide), with several
|
|
17
|
+
isolated regions.
|
|
18
|
+
|
|
19
|
+
The `AutoSpatialExtent` is an extension of the `pystac.SpatialExtent`.
|
|
20
|
+
|
|
21
|
+
Instances are initialized with the same arguments as `pystac.SpatialExtent`.
|
|
22
|
+
Internally, bounding boxes lists are processed at initialisation, so all
|
|
23
|
+
partially overlapping bounding boxes are merged and updated as a single one.
|
|
24
|
+
|
|
25
|
+
# AutoTemporalExtent
|
|
26
|
+
|
|
27
|
+
The `AutoTemporalExtent` is an extension of the `pystac.TemporalExtent`.
|
|
28
|
+
It computes the date min and date max of a set of dates or dates ranges.
|
|
29
|
+
|
|
30
|
+
"""
|
|
31
|
+
import pystac
|
|
32
|
+
from dataclasses import dataclass
|
|
33
|
+
from datetime import datetime
|
|
34
|
+
from typing import Union, List
|
|
35
|
+
from numbers import Number
|
|
36
|
+
from annotated_types import Predicate
|
|
37
|
+
from typing_extensions import Annotated
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def is_bbox(l: List) -> bool:
|
|
41
|
+
"""
|
|
42
|
+
Predicate to test is the input list represents a bounding box in WGS84.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
l: a list of `Number`
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
|
|
49
|
+
"""
|
|
50
|
+
if len(l) == 4:
|
|
51
|
+
if all(isinstance(i, Number) for i in l):
|
|
52
|
+
if -180 <= l[0] and -90 <= l[1] and l[2] <= 180 and l[3] <= 90:
|
|
53
|
+
if l[0] <= l[2] and l[1] <= l[3]:
|
|
54
|
+
return True
|
|
55
|
+
return False
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
Bbox = Annotated[list, Predicate(is_bbox)]
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@dataclass
|
|
62
|
+
class SmartBbox:
|
|
63
|
+
"""
|
|
64
|
+
Small class to work with a single 2D bounding box.
|
|
65
|
+
"""
|
|
66
|
+
coords: Bbox = None # [xmin, ymin, xmax, ymax]
|
|
67
|
+
|
|
68
|
+
def touches(self, other: "SmartBbox") -> bool:
|
|
69
|
+
"""
|
|
70
|
+
Overlap test.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
other: other bounding box
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
True if the other bounding box touches, else False.
|
|
77
|
+
|
|
78
|
+
"""
|
|
79
|
+
xmin, ymin, xmax, ymax = self.coords
|
|
80
|
+
o_xmin, o_ymin, o_xmax, o_ymax = other.coords
|
|
81
|
+
|
|
82
|
+
if xmax < o_xmin or o_xmax < xmin or ymax < o_ymin or o_ymax < ymin:
|
|
83
|
+
return False
|
|
84
|
+
return True
|
|
85
|
+
|
|
86
|
+
def update(self, other: "SmartBbox"):
|
|
87
|
+
"""
|
|
88
|
+
Update the coordinates of the Bbox. Modifies itself inplace.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
other: other bounding box
|
|
92
|
+
|
|
93
|
+
"""
|
|
94
|
+
if not self.coords:
|
|
95
|
+
self.coords = other.coords
|
|
96
|
+
else:
|
|
97
|
+
self.coords = [
|
|
98
|
+
min(self.coords[0], other.coords[0]),
|
|
99
|
+
min(self.coords[1], other.coords[1]),
|
|
100
|
+
max(self.coords[2], other.coords[2]),
|
|
101
|
+
max(self.coords[3], other.coords[3])
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def clusterize_bboxes(bboxes: list[Bbox]) -> list[Bbox]:
|
|
106
|
+
"""
|
|
107
|
+
Computes a list of bounding boxes regrouping all overlapping ones.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
bboxes: 2D bounding boxes (list of int of float)
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
list of 2D bounding boxes (list of int of float)
|
|
114
|
+
|
|
115
|
+
"""
|
|
116
|
+
bboxes = [SmartBbox(bbox) for bbox in bboxes]
|
|
117
|
+
clusters = [bboxes.pop()]
|
|
118
|
+
|
|
119
|
+
while bboxes:
|
|
120
|
+
bbox = bboxes.pop()
|
|
121
|
+
inter_clusters = [
|
|
122
|
+
i for i, cluster in enumerate(clusters) if bbox.touches(cluster)
|
|
123
|
+
]
|
|
124
|
+
if inter_clusters:
|
|
125
|
+
# We merge all intersecting clusters into one
|
|
126
|
+
clusters[inter_clusters[0]].update(bbox)
|
|
127
|
+
for i in inter_clusters[1:]:
|
|
128
|
+
clusters[inter_clusters[0]].update(clusters[i])
|
|
129
|
+
clusters = [
|
|
130
|
+
cluster
|
|
131
|
+
for i, cluster in enumerate(clusters)
|
|
132
|
+
if i not in inter_clusters[1:]
|
|
133
|
+
]
|
|
134
|
+
else:
|
|
135
|
+
clusters.append(bbox)
|
|
136
|
+
|
|
137
|
+
return [cluster.coords for cluster in clusters]
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class AutoSpatialExtent(pystac.SpatialExtent):
|
|
141
|
+
"""
|
|
142
|
+
Custom extension of pystac.SpatialExtent that automatically compute bboxes.
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
def __init__(self, *args, **kwargs):
|
|
146
|
+
"""
|
|
147
|
+
Initializer. Clusterize boxes after the original initializer.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
*args: args
|
|
151
|
+
**kwargs: keyword args
|
|
152
|
+
|
|
153
|
+
"""
|
|
154
|
+
super().__init__(*args, **kwargs)
|
|
155
|
+
self.clusterize_bboxes()
|
|
156
|
+
|
|
157
|
+
def update(self, other: pystac.SpatialExtent | Bbox):
|
|
158
|
+
"""
|
|
159
|
+
Updates itself with a new spatial extent or bounding box. Modifies
|
|
160
|
+
inplace `self.bboxes`.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
other: spatial extent or bbox coordinates
|
|
164
|
+
|
|
165
|
+
"""
|
|
166
|
+
is_spat_ext = isinstance(other, pystac.SpatialExtent)
|
|
167
|
+
self.bboxes += other.bboxes if is_spat_ext else other
|
|
168
|
+
self.clusterize_bboxes()
|
|
169
|
+
|
|
170
|
+
def clusterize_bboxes(self):
|
|
171
|
+
"""
|
|
172
|
+
Regroup the bounding boxes that overlap. Modifies inplace `self.bboxes`.
|
|
173
|
+
|
|
174
|
+
"""
|
|
175
|
+
self.bboxes = clusterize_bboxes(self.bboxes)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class AutoTemporalExtent(pystac.TemporalExtent):
|
|
179
|
+
"""
|
|
180
|
+
Custom extension of pystac.TemporalExtent that automatically updates itself
|
|
181
|
+
with another date or temporal extent provided.
|
|
182
|
+
"""
|
|
183
|
+
|
|
184
|
+
def __init__(self, *args, **kwargs):
|
|
185
|
+
"""
|
|
186
|
+
Initializer. Regroup all intervals into a single one.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
*args: args
|
|
190
|
+
**kwargs: keyword args
|
|
191
|
+
|
|
192
|
+
"""
|
|
193
|
+
super().__init__(*args, **kwargs)
|
|
194
|
+
self.make_single_interval()
|
|
195
|
+
|
|
196
|
+
def update(self, other: Union[pystac.TemporalExtent, datetime]):
|
|
197
|
+
"""
|
|
198
|
+
Updates itself with a new temporal extent of date. Modifies inplace
|
|
199
|
+
`self.intervals`.
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
other: temporal extent or datetime
|
|
203
|
+
|
|
204
|
+
"""
|
|
205
|
+
is_temp_ext = isinstance(other, pystac.TemporalExtent)
|
|
206
|
+
intervals = other.intervals if is_temp_ext else [[other, other]]
|
|
207
|
+
self.intervals += intervals
|
|
208
|
+
self.make_single_interval()
|
|
209
|
+
|
|
210
|
+
def make_single_interval(self):
|
|
211
|
+
all_dates = []
|
|
212
|
+
for dates_or_intervals in self.intervals:
|
|
213
|
+
# Because base class (`pystac.SpatialExtent`) converts everything
|
|
214
|
+
# into [[...]]
|
|
215
|
+
for date_or_interval in dates_or_intervals:
|
|
216
|
+
if isinstance(date_or_interval, (list, tuple)):
|
|
217
|
+
all_dates += [i for i in date_or_interval if i is not None]
|
|
218
|
+
elif isinstance(date_or_interval, datetime):
|
|
219
|
+
all_dates.append(date_or_interval)
|
|
220
|
+
else:
|
|
221
|
+
TypeError(f"Unsupported date/range of: {date_or_interval}")
|
|
222
|
+
self.intervals = \
|
|
223
|
+
[[min(all_dates), max(all_dates)]] if all_dates else [None, None]
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"item": {
|
|
3
|
+
"pattern": "(S1[ABCD]_IW_GRD[FHM_]_1S[SDHV][HV]_[0-9]{8}T[0-9]{6}_[0-9]{8}T[0-9]{6}_[0-9]{6}_[0-9A-Z]{6}_[0-9A-Z]{4})",
|
|
4
|
+
"properties": {
|
|
5
|
+
"datetime": {
|
|
6
|
+
"pattern": "S1[ABCD]_IW_GRD[FHM_]_1S[SDHV][HV]_([0-9]{8}T[0-9]{6})_.*",
|
|
7
|
+
"format": "%Y%m%dT%H%M%S"
|
|
8
|
+
},
|
|
9
|
+
"start_datetime": {
|
|
10
|
+
"pattern": "S1[ABCD]_IW_GRD[FHM_]_1S[SDHV][HV]_([0-9]{8}T[0-9]{6})_.*",
|
|
11
|
+
"format": "%Y%m%dT%H%M%S"
|
|
12
|
+
},
|
|
13
|
+
"end_datetime": {
|
|
14
|
+
"pattern": "S1[ABCD]_IW_GRD[FHM_]_1S[SDHV][HV]_[0-9]{8}T[0-9]{6}_([0-9]{8}T[0-9]{6})_.*",
|
|
15
|
+
"format": "%Y%m%dT%H%M%S"
|
|
16
|
+
},
|
|
17
|
+
"title": {
|
|
18
|
+
"pattern": "(S1[ABCD]_IW_GRD[FHM_]_1S[SDHV][HV]_[0-9]{8}T[0-9]{6}_[0-9]{8}T[0-9]{6}_[0-9]{6}_[0-9A-Z]{6}_[0-9A-Z]{4})"
|
|
19
|
+
},
|
|
20
|
+
"platform": {
|
|
21
|
+
"pattern": "(S1[ABCD]).+"
|
|
22
|
+
},
|
|
23
|
+
"sar:instrument_mode": "IW",
|
|
24
|
+
"sar:frequency_band": "C",
|
|
25
|
+
"sar:observation_direction": "right",
|
|
26
|
+
"sar:polarizations": ["VH", "VV"],
|
|
27
|
+
"sar:product_type": "GRD",
|
|
28
|
+
"sat:absolute_orbit": {
|
|
29
|
+
"pattern" : "S1[ABCD]_IW_GRD[FHM_]_1S[SDHV][HV]_[0-9]{8}T[0-9]{6}_[0-9]{8}T[0-9]{6}_([0-9]{6})_[0-9A-Z]{6}_[0-9A-Z]{4}"
|
|
30
|
+
},
|
|
31
|
+
"s1:datatake_id": {
|
|
32
|
+
"pattern" : "S1[ABCD]_IW_GRD[FHM_]_1S[SDHV][HV]_[0-9]{8}T[0-9]{6}_[0-9]{8}T[0-9]{6}_[0-9]{6}_([0-9A-Z]{6})_[0-9A-Z]{4}"
|
|
33
|
+
},
|
|
34
|
+
"s1:product_identifier": {
|
|
35
|
+
"pattern" : "(S1[ABCD]_IW_GRD[FHM_]_1S[SDHV][HV]_[0-9]{8}T[0-9]{6}_[0-9]{8}T[0-9]{6}_[0-9]{6}_[0-9A-Z]{6}_[0-9A-Z]{4})"
|
|
36
|
+
},
|
|
37
|
+
"s1:resolution": {
|
|
38
|
+
"pattern": "S1[ABCD]_IW_GRD([FHM_])_1S[SDHV][HV]_[0-9]{8}T[0-9]{6}_[0-9]{8}T[0-9]{6}_[0-9]{6}_[0-9A-Z]{6}_[0-9A-Z]{4}"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"stac_extensions": ["sar", "sat"]
|
|
42
|
+
},
|
|
43
|
+
"item_assets": {
|
|
44
|
+
"vv": {
|
|
45
|
+
"pattern": "s1[abcd]-iw-grd-vv.+\\.tiff",
|
|
46
|
+
"roles": ["data"],
|
|
47
|
+
"eo:bands": [{
|
|
48
|
+
"name": "VV",
|
|
49
|
+
"description": "VV band: vertical transmit and vertical receive"
|
|
50
|
+
}]
|
|
51
|
+
},
|
|
52
|
+
"vh": {
|
|
53
|
+
"pattern": "s1[abcd]-iw-grd-vh.+\\.tiff",
|
|
54
|
+
"roles": ["data"],
|
|
55
|
+
"eo:bands": [{
|
|
56
|
+
"name": "VH",
|
|
57
|
+
"description": "VH band: vertical transmit and horizontal receive" }]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"item": {
|
|
3
|
+
"pattern": "(S1[ABCD]_L1ORT_[0-9]{2}[A-Z]{3}_GAM_[A-Z]{3}_[0-9]{3}_[0-9]{8}T[0-9]{6})",
|
|
4
|
+
"properties": {
|
|
5
|
+
"datetime": {
|
|
6
|
+
"pattern": "S1[ABCD]_L1ORT_[0-9]{2}[A-Z]{3}_GAM_[A-Z]{3}_[0-9]{3}_([0-9]{8}T[0-9]{6})",
|
|
7
|
+
"format": "%Y%m%dT%H%M%S"
|
|
8
|
+
},
|
|
9
|
+
"start_datetime": {
|
|
10
|
+
"pattern": "S1[ABCD]_L1ORT_[0-9]{2}[A-Z]{3}_GAM_[A-Z]{3}_[0-9]{3}_([0-9]{8}T[0-9]{6})",
|
|
11
|
+
"format": "%Y%m%dT%H%M%S"
|
|
12
|
+
},
|
|
13
|
+
"end_datetime": {
|
|
14
|
+
"pattern": "S1[ABCD]_L1ORT_[0-9]{2}[A-Z]{3}_GAM_[A-Z]{3}_[0-9]{3}_([0-9]{8}T[0-9]{6})",
|
|
15
|
+
"format": "%Y%m%dT%H%M%S"
|
|
16
|
+
},
|
|
17
|
+
"title": {
|
|
18
|
+
"pattern": "(S1[ABCD]_L1ORT_[0-9]{2}[A-Z]{3}_GAM_[A-Z]{3}_[0-9]{3}_[0-9]{8}T[0-9]{6})"
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
"sat:orbit_state": {
|
|
22
|
+
"pattern": "S1[ABCD]_L1ORT_[0-9]{2}[A-Z]{3}_GAM_([A-Z]{3})_[0-9]{3}_[0-9]{8}T[0-9]{6}"
|
|
23
|
+
},
|
|
24
|
+
"sar:frequency_band": "C",
|
|
25
|
+
"sar:observation_direction": "right",
|
|
26
|
+
"sar:polarizations": ["VH", "VV"],
|
|
27
|
+
"sar:product_type": "GRD_S1Tiling",
|
|
28
|
+
"sar:instrument_mode": "IW",
|
|
29
|
+
"sat:relative_orbit": {
|
|
30
|
+
"pattern" : "S1[ABCD]_L1ORT_[0-9]{2}[A-Z]{3}_GAM_[A-Z]{3}_([0-9]{3})_[0-9]{8}T[0-9]{6}"
|
|
31
|
+
},
|
|
32
|
+
"grid:code": {
|
|
33
|
+
"pattern" : "S1[ABCD]_L1ORT_([0-9]{2}[A-Z]{3})_GAM_[A-Z]{3}_[0-9]{3}_[0-9]{8}T[0-9]{6}"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"stac_extensions": ["sar", "sat", "grid"]
|
|
37
|
+
},
|
|
38
|
+
"item_assets": {
|
|
39
|
+
"vv": {
|
|
40
|
+
"pattern": "S1[ABCD]_L1ORT_[0-9]{2}[A-Z]{3}_VV_GAM_[A-Z]{3}_[0-9]{3}_[0-9]{8}T[0-9]{6}\\.tif",
|
|
41
|
+
"roles": ["data"],
|
|
42
|
+
"eo:bands": [{
|
|
43
|
+
"name": "VV",
|
|
44
|
+
"description": "VV band: vertical transmit and vertical receive"
|
|
45
|
+
}]
|
|
46
|
+
},
|
|
47
|
+
"vh": {
|
|
48
|
+
"pattern": "S1[ABCD]_L1ORT_[0-9]{2}[A-Z]{3}_VH_GAM_[A-Z]{3}_[0-9]{3}_[0-9]{8}T[0-9]{6}\\.tif",
|
|
49
|
+
"roles": ["data"],
|
|
50
|
+
"eo:bands": [{
|
|
51
|
+
"name": "VH",
|
|
52
|
+
"description": "VH band: vertical transmit and horizontal receive" }]
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
{
|
|
2
|
+
"item" : {
|
|
3
|
+
"pattern" : "(SENTINEL2[ABC]_[0-9]{8}-[0-9]{6}-[0-9]{3}_L2A_T[0-9A-Z]{5}_[A-Z]_V[0-9]-[0-9])$",
|
|
4
|
+
"properties": {
|
|
5
|
+
"datetime" : {
|
|
6
|
+
"pattern" : "SENTINEL2[ABC]_([0-9]{8}-[0-9]{6})-.*",
|
|
7
|
+
"format" : "%Y%m%d-%H%M%S"
|
|
8
|
+
},
|
|
9
|
+
"title" : {
|
|
10
|
+
"pattern" : "(SENTINEL2[ABC]_[0-9]{8}-[0-9]{6}-[0-9]{3}_L2A_T[0-9A-Z]{5}_[A-Z]_V[0-9]-[0-9])"
|
|
11
|
+
},
|
|
12
|
+
"grid:code" : {
|
|
13
|
+
"pattern" : ".+_T([0-9A-Z]{5})_.+"
|
|
14
|
+
},
|
|
15
|
+
"platform" : {
|
|
16
|
+
"pattern" : "(SENTINEL2[ABC]).+"
|
|
17
|
+
},
|
|
18
|
+
"constellation": "sentinel-2",
|
|
19
|
+
"instruments" : ["msi"],
|
|
20
|
+
"product:type" : "S2MSI2A"
|
|
21
|
+
},
|
|
22
|
+
"stac_extensions": ["grid"]
|
|
23
|
+
},
|
|
24
|
+
"item_assets" : {
|
|
25
|
+
"B02" : {
|
|
26
|
+
"pattern" : ".+_FRE_B2\\.tif",
|
|
27
|
+
"roles" : ["reflectance"],
|
|
28
|
+
"eo:bands" : [{
|
|
29
|
+
"name" : "B02",
|
|
30
|
+
"common_name" : "blue",
|
|
31
|
+
"center_wavelength": 0.4966,
|
|
32
|
+
"full_width_half_max": 0.098
|
|
33
|
+
}]
|
|
34
|
+
},
|
|
35
|
+
"B03" : {
|
|
36
|
+
"pattern" : ".+_FRE_B3\\.tif",
|
|
37
|
+
"roles" : ["reflectance"],
|
|
38
|
+
"eo:bands" : [{
|
|
39
|
+
"name" : "B03",
|
|
40
|
+
"common_name" : "green",
|
|
41
|
+
"center_wavelength": 0.56,
|
|
42
|
+
"full_width_half_max": 0.045
|
|
43
|
+
}]
|
|
44
|
+
},
|
|
45
|
+
"B04" : {
|
|
46
|
+
"pattern" : ".+_FRE_B4\\.tif",
|
|
47
|
+
"roles" : ["reflectance"],
|
|
48
|
+
"eo:bands" : [{
|
|
49
|
+
"name" : "B04",
|
|
50
|
+
"common_name" : "red",
|
|
51
|
+
"center_wavelength": 0.6645,
|
|
52
|
+
"full_width_half_max": 0.038
|
|
53
|
+
}]
|
|
54
|
+
},
|
|
55
|
+
"B05" : {
|
|
56
|
+
"pattern" : ".+_FRE_B5\\.tif",
|
|
57
|
+
"roles" : ["reflectance"],
|
|
58
|
+
"eo:bands" : [{
|
|
59
|
+
"name" : "B05",
|
|
60
|
+
"common_name" : "rededge",
|
|
61
|
+
"center_wavelength": 0.7039,
|
|
62
|
+
"full_width_half_max": 0.019
|
|
63
|
+
}]
|
|
64
|
+
},
|
|
65
|
+
"B06" : {
|
|
66
|
+
"pattern" : ".+_FRE_B6\\.tif",
|
|
67
|
+
"roles" : ["reflectance"],
|
|
68
|
+
"eo:bands" : [{
|
|
69
|
+
"name" : "B06",
|
|
70
|
+
"common_name" : "rededge",
|
|
71
|
+
"center_wavelength": 0.7402,
|
|
72
|
+
"full_width_half_max": 0.018
|
|
73
|
+
}]
|
|
74
|
+
},
|
|
75
|
+
"B07" : {
|
|
76
|
+
"pattern" : ".+_FRE_B7\\.tif",
|
|
77
|
+
"roles" : ["reflectance"],
|
|
78
|
+
"eo:bands" : [{
|
|
79
|
+
"name" : "B07",
|
|
80
|
+
"common_name" : "rededge",
|
|
81
|
+
"center_wavelength": 0.7825,
|
|
82
|
+
"full_width_half_max": 0.028
|
|
83
|
+
}]
|
|
84
|
+
},
|
|
85
|
+
"B08" : {
|
|
86
|
+
"pattern" : ".+_FRE_B8\\.tif",
|
|
87
|
+
"roles" : ["reflectance"],
|
|
88
|
+
"eo:bands" : [{
|
|
89
|
+
"name" : "B08",
|
|
90
|
+
"common_name" : "nir",
|
|
91
|
+
"center_wavelength": 0.8351,
|
|
92
|
+
"full_width_half_max": 0.145
|
|
93
|
+
}]
|
|
94
|
+
},
|
|
95
|
+
"B8A" : {
|
|
96
|
+
"pattern" : ".+_FRE_B8A\\.tif",
|
|
97
|
+
"roles" : ["reflectance"],
|
|
98
|
+
"eo:bands" : [{
|
|
99
|
+
"name" : "B8A",
|
|
100
|
+
"common_name" : "nir08",
|
|
101
|
+
"center_wavelength": 0.8648,
|
|
102
|
+
"full_width_half_max": 0.033
|
|
103
|
+
}]
|
|
104
|
+
},
|
|
105
|
+
"B11" : {
|
|
106
|
+
"pattern" : ".+_FRE_B11\\.tif",
|
|
107
|
+
"roles" : ["reflectance"],
|
|
108
|
+
"eo:bands" : [{
|
|
109
|
+
"name" : "B11",
|
|
110
|
+
"common_name" : "swir16",
|
|
111
|
+
"center_wavelength": 1.6137,
|
|
112
|
+
"full_width_half_max": 0.143
|
|
113
|
+
}]
|
|
114
|
+
},
|
|
115
|
+
"B12" : {
|
|
116
|
+
"pattern" : ".+_FRE_B12\\.tif",
|
|
117
|
+
"roles" : ["reflectance"],
|
|
118
|
+
"eo:bands" : [{
|
|
119
|
+
"name" : "B12",
|
|
120
|
+
"common_name" : "swir22",
|
|
121
|
+
"center_wavelength": 2.22024,
|
|
122
|
+
"full_width_half_max": 0.242
|
|
123
|
+
}]
|
|
124
|
+
},
|
|
125
|
+
"CLM_R1" : {
|
|
126
|
+
"pattern" : ".+_CLM_R1\\.tif",
|
|
127
|
+
"roles" : ["data"]
|
|
128
|
+
},
|
|
129
|
+
"CLM_R2" : {
|
|
130
|
+
"pattern" : ".+_CLM_R2\\.tif",
|
|
131
|
+
"roles" : ["data"]
|
|
132
|
+
},
|
|
133
|
+
"SAT_R1" : {
|
|
134
|
+
"pattern" : ".+_SAT_R1\\.tif",
|
|
135
|
+
"roles" : ["data"]
|
|
136
|
+
},
|
|
137
|
+
"SAT_R2" : {
|
|
138
|
+
"pattern" : ".+_SAT_R2\\.tif",
|
|
139
|
+
"roles" : ["data"]
|
|
140
|
+
},
|
|
141
|
+
"EDG_R1" : {
|
|
142
|
+
"pattern" : ".+_EDG_R1\\.tif",
|
|
143
|
+
"roles" : ["data"]
|
|
144
|
+
},
|
|
145
|
+
"EDG_R2" : {
|
|
146
|
+
"pattern" : ".+_EDG_R2\\.tif",
|
|
147
|
+
"roles" : ["data"]
|
|
148
|
+
},
|
|
149
|
+
"MG2_R1" : {
|
|
150
|
+
"pattern" : ".+_MG2_R1\\.tif",
|
|
151
|
+
"roles" : ["data"]
|
|
152
|
+
},
|
|
153
|
+
"MG2_R2" : {
|
|
154
|
+
"pattern" : ".+_MG2_R2\\.tif",
|
|
155
|
+
"roles" : ["data"]
|
|
156
|
+
},
|
|
157
|
+
"IAB_R1" : {
|
|
158
|
+
"pattern" : ".+_IAB_R1\\.tif",
|
|
159
|
+
"roles" : ["data"]
|
|
160
|
+
},
|
|
161
|
+
"IAB_R2" : {
|
|
162
|
+
"pattern" : ".+_IAB_R2\\.tif",
|
|
163
|
+
"roles" : ["data"]
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Common Name Band Range (μm) Landsat 5/7 Landsat 8 Sentinel 2 MODIS NAIP
|
|
2
|
+
coastal 0.40 - 0.45 1 1
|
|
3
|
+
blue 0.45 - 0.50 1 2 2 3 3
|
|
4
|
+
green 0.50 - 0.60 2 3 3 4 2
|
|
5
|
+
red 0.60 - 0.70 3 4 4 1 1
|
|
6
|
+
yellow 0.58 - 0.62
|
|
7
|
+
pan 0.50 - 0.70 8 (L7 only) 8
|
|
8
|
+
rededge 0.70 - 0.79 5, 6, 7
|
|
9
|
+
nir 0.75 - 1.00 4 8 2 4
|
|
10
|
+
nir08 0.75 - 0.90 5 8a
|
|
11
|
+
nir09 0.85 - 1.05 9
|
|
12
|
+
cirrus 1.35 - 1.40 9 10 26
|
|
13
|
+
swir16 1.55 - 1.75 5 6 11 6
|
|
14
|
+
swir22 2.10 - 2.30 7 7 12 7
|
|
15
|
+
lwir 10.5 - 12.5 6
|
|
16
|
+
lwir11 10.5 - 11.5 10 31
|
|
17
|
+
lwir12 11.5 - 12.5 11 32
|