1717from openeogeotrellis .constants import EVAL_ENV_KEY
1818
1919import openeogeotrellis .load_stac
20+ from openeogeotrellis .util .caching import GetOrCallCache , GetOrCallCacheInterface , AlwaysCallWithoutCache
2021from openeogeotrellis .util .geometry import BoundingBoxMerger
2122from openeogeotrellis .util .math import logarithmic_round
2223
@@ -198,7 +199,10 @@ class AlignedExtentResult:
198199
199200
200201def _extract_spatial_extent_from_constraint (
201- source_constraint : SourceConstraint , * , catalog : AbstractCollectionCatalog
202+ source_constraint : SourceConstraint ,
203+ * ,
204+ catalog : AbstractCollectionCatalog ,
205+ cache : Optional [GetOrCallCacheInterface ] = None ,
202206) -> Union [None , AlignedExtentResult ]:
203207 """
204208 Extract spatial extent from given source constraint (if any), and align it to target grid.
@@ -211,18 +215,22 @@ def _extract_spatial_extent_from_constraint(
211215 if source_process == "load_collection" :
212216 collection_id = source_id [1 ][0 ]
213217 return _extract_spatial_extent_from_constraint_load_collection (
214- collection_id = collection_id , constraint = constraint , catalog = catalog
218+ collection_id = collection_id , constraint = constraint , catalog = catalog , cache = cache
215219 )
216220 elif source_process == "load_stac" :
217221 url = source_id [1 ][0 ]
218- return _extract_spatial_extent_from_constraint_load_stac (stac_url = url , constraint = constraint )
222+ return _extract_spatial_extent_from_constraint_load_stac (stac_url = url , constraint = constraint , cache = cache )
219223 else :
220224 # TODO?
221225 return None
222226
223227
224228def _extract_spatial_extent_from_constraint_load_collection (
225- collection_id : str , * , constraint : dict , catalog : AbstractCollectionCatalog
229+ collection_id : str ,
230+ * ,
231+ constraint : dict ,
232+ catalog : AbstractCollectionCatalog ,
233+ cache : Optional [GetOrCallCacheInterface ] = None ,
226234) -> Union [None , AlignedExtentResult ]:
227235 try :
228236 metadata = catalog .get_collection_metadata (collection_id )
@@ -233,7 +241,7 @@ def _extract_spatial_extent_from_constraint_load_collection(
233241 stac_url = deep_get (metadata , "_vito" , "data_source" , "url" )
234242 load_stac_feature_flags = deep_get (metadata , "_vito" , "data_source" , "load_stac_feature_flags" , default = {})
235243 return _extract_spatial_extent_from_constraint_load_stac (
236- stac_url = stac_url , constraint = constraint , feature_flags = load_stac_feature_flags
244+ stac_url = stac_url , constraint = constraint , feature_flags = load_stac_feature_flags , cache = cache
237245 )
238246
239247 # TODO Extracting pixel grid info from collection metadata might might be unreliable
@@ -272,7 +280,11 @@ def _extract_spatial_extent_from_constraint_load_collection(
272280
273281
274282def _extract_spatial_extent_from_constraint_load_stac (
275- stac_url : str , * , constraint : dict , feature_flags : Optional [dict ] = None
283+ stac_url : str ,
284+ * ,
285+ constraint : dict ,
286+ feature_flags : Optional [dict ] = None ,
287+ cache : Optional [GetOrCallCacheInterface ] = None ,
276288) -> Union [None , AlignedExtentResult ]:
277289 spatial_extent_from_pg = constraint .get ("spatial_extent" ) or constraint .get ("weak_spatial_extent" )
278290 spatiotemporal_extent = openeogeotrellis .load_stac ._spatiotemporal_extent_from_load_params (
@@ -293,12 +305,23 @@ def _extract_spatial_extent_from_constraint_load_stac(
293305
294306 pixel_buffer_size = deep_get (constraint , "pixel_buffer" , "buffer_size" , default = None )
295307
296- return _extract_spatial_extent_from_load_stac_item_collection (
297- stac_url = stac_url ,
298- spatiotemporal_extent = spatiotemporal_extent ,
299- property_filter_pg_map = property_filter_pg_map ,
300- resample_grid = resample_grid ,
301- pixel_buffer_size = pixel_buffer_size ,
308+ return (cache or AlwaysCallWithoutCache ()).get_or_call (
309+ key = (
310+ stac_url ,
311+ spatiotemporal_extent ,
312+ str (property_filter_pg_map ),
313+ resample_grid ,
314+ pixel_buffer_size ,
315+ str (feature_flags ),
316+ ),
317+ callback = lambda : _extract_spatial_extent_from_load_stac_item_collection (
318+ stac_url = stac_url ,
319+ spatiotemporal_extent = spatiotemporal_extent ,
320+ property_filter_pg_map = property_filter_pg_map ,
321+ resample_grid = resample_grid ,
322+ pixel_buffer_size = pixel_buffer_size ,
323+ feature_flags = feature_flags ,
324+ ),
302325 )
303326
304327
@@ -309,6 +332,7 @@ def _extract_spatial_extent_from_load_stac_item_collection(
309332 property_filter_pg_map : Optional [openeogeotrellis .load_stac .PropertyFilterPGMap ] = None ,
310333 resample_grid : Optional [_GridInfo ] = None ,
311334 pixel_buffer_size : Union [Tuple [float , float ], int , float , None ] = None ,
335+ feature_flags : Optional [dict ] = None ,
312336) -> Union [None , AlignedExtentResult ]:
313337 extent_orig : Union [BoundingBox , None ] = spatiotemporal_extent .spatial_extent .as_bbox ()
314338 extent_variants = {"original" : extent_orig }
@@ -430,6 +454,7 @@ def determine_global_extent(
430454 * ,
431455 source_constraints : List [SourceConstraint ],
432456 catalog : AbstractCollectionCatalog ,
457+ cache : Optional [GetOrCallCacheInterface ] = None ,
433458) -> dict :
434459 """
435460 Go through all source constraints, extract the aligned extent from each (possibly with variations)
@@ -439,9 +464,16 @@ def determine_global_extent(
439464 # e.g. add stats to AlignedExtentResult for better informed decision?
440465 aligned_merger = BoundingBoxMerger ()
441466 variant_mergers : Dict [str , BoundingBoxMerger ] = collections .defaultdict (BoundingBoxMerger )
467+ # Enable the implementation to use caching
468+ # when going through all these source constraints
469+ # as there might be duplication that's hidden
470+ # by differences from non-relevant details
471+ cache = cache or GetOrCallCache (max_size = 100 )
442472 for source_id , constraint in source_constraints :
443473 try :
444- aligned_extent_result = _extract_spatial_extent_from_constraint ((source_id , constraint ), catalog = catalog )
474+ aligned_extent_result = _extract_spatial_extent_from_constraint (
475+ (source_id , constraint ), catalog = catalog , cache = cache
476+ )
445477 except Exception as e :
446478 raise SpatialExtentExtractionError (
447479 f"Failed to extract spatial extent from { source_id = } with { constraint = } : { e = } "
@@ -456,6 +488,7 @@ def determine_global_extent(
456488 _log .info (
457489 f"determine_global_extent: skipping { name = } from { source_id = } with { aligned_extent_result .variants = } "
458490 )
491+ _log .info (f"_extract_spatial_extent_from_constraint cache stats: { cache !s} " )
459492
460493 global_extent : BoundingBox = aligned_merger .get ()
461494 global_extent_variants : Dict [str , BoundingBox ] = {name : merger .get () for name , merger in variant_mergers .items ()}
0 commit comments