Skip to content

Commit 89c4047

Browse files
committed
reinstate COG reader, make window boundless, fix dst/src window transform
1 parent e242376 commit 89c4047

File tree

1 file changed

+100
-1
lines changed

1 file changed

+100
-1
lines changed

src/satextractor/extractor/extractor.py

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,39 @@
1414
from satextractor.models import Tile
1515

1616

17+
def get_window_union(
18+
tiles: List[Tile],
19+
ds: rasterio.io.DatasetReader,
20+
) -> rasterio.windows.Window:
21+
22+
"""Get the window union to read all tiles from the geotiff.
23+
24+
Args:
25+
tiles (List[Tile]): the tiles
26+
ds (rasterio.io.DatasetReader): the rasterio dataset to read (for the transform)
27+
28+
Returns:
29+
rasterio.windows.Window: The union of all tile windows.
30+
"""
31+
32+
windows = []
33+
34+
for tile in tiles:
35+
36+
bounds_arr_tile_crs = tile.bbox
37+
bounds_arr_rast_crs = warp.transform_bounds(
38+
CRS.from_epsg(tile.epsg),
39+
ds.crs,
40+
*bounds_arr_tile_crs,
41+
)
42+
43+
window = rasterio.windows.from_bounds(*bounds_arr_rast_crs, ds.transform)
44+
45+
windows.append(window)
46+
47+
return rasterio.windows.union(windows)
48+
49+
1750
def get_proj_win(tiles: List[Tile]) -> Tuple[int, int, int, int]:
1851
"""Get the projection bounds window of the tiles.
1952
@@ -47,6 +80,68 @@ def get_tile_pixel_coords(tiles: List[Tile], raster_file: str) -> List[Tuple[int
4780

4881
return list(zip(rows, cols))
4982

83+
def download_and_extract_tiles_window_COG(
84+
fs: Any,
85+
task: ExtractionTask,
86+
resolution: int,
87+
) -> List[str]:
88+
"""Download and extract from the task assets the data for the window from each asset.
89+
90+
Args:
91+
task (ExtractionTask): The extraction task
92+
resolution (int): The target resolution
93+
94+
Returns:
95+
List[str]: A list of files that store the crops of the original assets
96+
"""
97+
98+
# task tiles all have same CRS, so get their max extents and crs
99+
left, top, right, bottom = get_proj_win(task.tiles)
100+
epsg = task.tiles[0].epsg
101+
102+
# set the transforms for the output file
103+
dst_transform = Affine(resolution, 0.0, left, 0.0, -resolution, top)
104+
out_shp = (int((right - left) / resolution), int((top - bottom) / resolution))
105+
106+
outfiles = []
107+
108+
band = task.band
109+
urls = [item.assets[band].href for item in task.item_collection.items]
110+
111+
for ii, url in enumerate(urls):
112+
with fs.open(url) as f:
113+
with rasterio.open(f) as ds:
114+
window = get_window_union(task.tiles, ds)
115+
116+
rst_arr = ds.read(
117+
1,
118+
window=window,
119+
out_shape=out_shp,
120+
fill_value=0,
121+
boundless=True,
122+
)
123+
124+
out_f = f"{task.task_id}_{ii}.tif"
125+
126+
with rasterio.open(
127+
out_f,
128+
"w",
129+
driver="GTiff",
130+
count=1,
131+
width=out_shp[0],
132+
height=out_shp[1],
133+
transform=dst_transform,
134+
crs=CRS.from_epsg(epsg),
135+
dtype=rst_arr.dtype,
136+
) as dst:
137+
138+
dst.write(rst_arr, indexes=1)
139+
140+
outfiles.append(out_f)
141+
142+
return outfiles
143+
144+
50145

51146
def download_and_extract_tiles_window(
52147
download_f: Callable,
@@ -128,7 +223,11 @@ def task_mosaic_patches(
128223
Returns:
129224
List[np.ndarray]: The tile patches as numpy arrays
130225
"""
131-
out_files = download_and_extract_tiles_window(download_f, task, resolution)
226+
227+
if task.constellation == "sentinel-2":
228+
out_files = download_and_extract_tiles_window(download_f, task, resolution)
229+
else:
230+
out_files = download_and_extract_tiles_window_COG(cloud_fs, task, resolution)
132231

133232
out_f = f"{task.task_id}_{dst_path}"
134233
datasets = [rasterio.open(f) for f in out_files]

0 commit comments

Comments
 (0)