1111import fs
1212import pandas as pd
1313import requests
14- from geopandas import GeoDataFrame
15- from pydantic import Field
14+ from pydantic import Field , validator
1615from typing_extensions import ParamSpec
1716
1817from sentinelhub import (
19- CRS ,
2018 BatchProcessClient ,
2119 BatchProcessRequest ,
2220 BatchRequestStatus ,
@@ -125,9 +123,23 @@ class BatchDownloadPipeline(Pipeline):
125123 provided via the CustomGridAreaManager.
126124 """
127125
126+ NAME_COLUMN = "identifier"
127+
128128 class Schema (Pipeline .Schema ):
129129 area : CustomGridAreaManager .Schema
130130
131+ @validator ("area" )
132+ def _parse_area_name_column (cls , area : CustomGridAreaManager .Schema ) -> CustomGridAreaManager .Schema :
133+ name_column = area .name_column
134+ if name_column != BatchDownloadPipeline .NAME_COLUMN :
135+ raise AssertionError (
136+ (
137+ "Name column of CustomGridAreaManager used in BatchDownloadPipeline should be "
138+ f"set to '{ BatchDownloadPipeline .NAME_COLUMN } ' for proper functionality."
139+ )
140+ )
141+ return area
142+
131143 iam_role_arn : str = Field (description = "IAM role ARN for the batch job." )
132144
133145 output_folder_key : str = Field (
@@ -263,14 +275,21 @@ def _get_aoi_geometry(self) -> Geometry:
263275
264276 def _create_and_save_batch_grid (self ) -> str :
265277 """Creates a saves the grid used for Batch Process API"""
266- grid = create_batch_grid (
278+ grid = create_utm_zone_grid (
267279 geometry = self ._get_aoi_geometry (),
280+ name_column = self .NAME_COLUMN ,
268281 bbox_size = self .config .grid .bbox_size ,
269282 bbox_offset = self .config .grid .bbox_offset ,
270283 bbox_buffer = self .config .grid .bbox_buffer ,
271- image_size = self .config .grid .image_size ,
272- resolution = self .config .grid .resolution ,
273284 )
285+
286+ width , height = self .config .grid .image_size
287+ for crs , gdf in grid .items ():
288+ gdf ["width" ] = width
289+ gdf ["height" ] = height
290+ gdf ["resolution" ] = self .config .grid .resolution
291+ grid [crs ] = gdf
292+
274293 grid_folder = self .storage .get_folder (self .area_manager .config .grid_folder_key )
275294 grid_path = fs .path .join (grid_folder , self .area_manager .config .grid_filename )
276295 save_grid (grid , grid_path , self .storage )
@@ -287,7 +306,7 @@ def _update_batch_grid(self, batch_request_id: str) -> None:
287306 fm = load_grid (fm_path , self .storage )
288307
289308 for crs , crs_grid in grid .items ():
290- grid [crs ] = crs_grid [crs_grid . identifier .isin (fm [crs ]. identifier .unique ())]
309+ grid [crs ] = crs_grid [crs_grid [ self . NAME_COLUMN ] .isin (fm [crs ][ self . NAME_COLUMN ] .unique ())]
291310
292311 save_grid (grid , grid_path , self .storage )
293312
@@ -395,30 +414,3 @@ def _get_tiles_per_status(self, batch_request_id: str) -> dict[str, list[str]]:
395414 conn = sqlite3 .connect (local_file .path )
396415 db_df = pd .read_sql ("SELECT * FROM features" , conn )
397416 return db_df .groupby ("status" ).name .apply (list ).to_dict ()
398-
399-
400- def create_batch_grid (
401- geometry : Geometry ,
402- bbox_size : tuple [int , int ],
403- bbox_offset : tuple [float , float ],
404- bbox_buffer : tuple [float , float ],
405- image_size : tuple [int , int ],
406- resolution : int ,
407- ) -> dict [CRS , GeoDataFrame ]:
408- """Creates a grid of bounding boxes covering the given area that is suitable for use with Batch Processing API."""
409- grid = create_utm_zone_grid (
410- geometry = geometry ,
411- name_column = "identifier" ,
412- bbox_size = bbox_size ,
413- bbox_offset = bbox_offset ,
414- bbox_buffer = bbox_buffer ,
415- )
416-
417- width , height = image_size
418- for crs , gdf in grid .items ():
419- gdf ["width" ] = width
420- gdf ["height" ] = height
421- gdf ["resolution" ] = resolution
422- grid [crs ] = gdf
423-
424- return grid
0 commit comments