|
14 | 14 | from satextractor.models import Tile |
15 | 15 |
|
16 | 16 |
|
| 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 | + |
17 | 50 | def get_proj_win(tiles: List[Tile]) -> Tuple[int, int, int, int]: |
18 | 51 | """Get the projection bounds window of the tiles. |
19 | 52 |
|
@@ -47,6 +80,68 @@ def get_tile_pixel_coords(tiles: List[Tile], raster_file: str) -> List[Tuple[int |
47 | 80 |
|
48 | 81 | return list(zip(rows, cols)) |
49 | 82 |
|
| 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 | + |
50 | 145 |
|
51 | 146 | def download_and_extract_tiles_window( |
52 | 147 | download_f: Callable, |
@@ -128,7 +223,11 @@ def task_mosaic_patches( |
128 | 223 | Returns: |
129 | 224 | List[np.ndarray]: The tile patches as numpy arrays |
130 | 225 | """ |
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) |
132 | 231 |
|
133 | 232 | out_f = f"{task.task_id}_{dst_path}" |
134 | 233 | datasets = [rasterio.open(f) for f in out_files] |
|
0 commit comments