Skip to content

Commit 5d324a7

Browse files
committed
OPTIM: Use raw band path over default band path to speed up the computation of image information (extent, footprint, CRS, transform) of SAR ortho products
1 parent c84c9b9 commit 5d324a7

3 files changed

Lines changed: 55 additions & 57 deletions

File tree

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- FIX: Add a fallback in case of impossibleness of reading ICEYE `QUICKLOOK.kml` file
1414
- FIX: Manage the case of Maxar data with negative absolute calibration factor: don't compute the reflectance and leave it as is.
1515
- FIX: Fix DEM management with RPC orthorectification: handle correctly the vertical CRS (see DEM notebook and `EOREADER_DEM_VCRS` environment variable). [#53](https://github.com/sertit/eoreader/issues/53)
16+
- OPTIM: Use raw band path over default band path to speed up the computation of image information (extent, footprint, CRS, transform) of SAR ortho products
1617
- CI: Filter some warnings in pytest
1718

1819
## 0.22.4 (2025-07-07)

eoreader/products/sar/sar_product.py

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
import rasterio
2929
import rioxarray
3030
import xarray as xr
31-
from rasterio import crs
31+
from affine import Affine
32+
from rasterio import CRS, crs
3233
from rasterio.enums import Resampling
3334
from rasterio.windows import Window
3435
from sertit import AnyPath, geometry, misc, path, rasters, snap, strings, types, vectors
@@ -287,15 +288,46 @@ def footprint(self) -> gpd.GeoDataFrame:
287288
Returns:
288289
gpd.GeoDataFrame: Footprint as a GeoDataFrame
289290
"""
291+
if self.is_ortho:
292+
default_band_path = self.get_raw_band_paths()[self.get_default_band()]
293+
else:
294+
default_band_path = self.get_default_band_path()
295+
290296
# Processed by SNAP: the nodata is set -> use get_footprint instead of vectorize
291297
downsampled_band = utils.read(
292-
self.get_default_band_path(),
298+
default_band_path,
293299
pixel_size=max(
294300
self.resolution * 10, float(os.environ.get(SAR_DEF_PIXEL_SIZE, 0))
295301
),
296302
)
297303
return rasters.get_footprint(downsampled_band)
298304

305+
@cache
306+
def default_transform(self, **kwargs) -> (Affine, int, int, CRS):
307+
"""
308+
Returns default transform data of the default band (UTM),
309+
as the :code:`rasterio.warp.calculate_default_transform` does:
310+
- transform
311+
- width
312+
- height
313+
- crs
314+
315+
Args:
316+
kwargs: Additional arguments
317+
Returns:
318+
Affine, int, int, CRS: transform, width, height, CRS
319+
320+
"""
321+
if self.is_ortho:
322+
default_band_path = self.get_raw_band_paths(**kwargs)[
323+
self.get_default_band()
324+
]
325+
else:
326+
default_band_path = self.get_default_band_path(**kwargs)
327+
328+
with rasterio.open(str(default_band_path)) as dst:
329+
return dst.transform, dst.width, dst.height, dst.crs
330+
299331
def get_default_band(self) -> BandNames:
300332
"""
301333
Get default band:
@@ -398,11 +430,16 @@ def extent(self) -> gpd.GeoDataFrame:
398430
Returns:
399431
gpd.GeoDataFrame: Extent in UTM
400432
"""
401-
# Get WGS84 extent
402-
extent_wgs84 = self.wgs84_extent()
433+
if self.is_ortho:
434+
return rasters.get_extent(
435+
self.get_raw_band_paths()[self.get_default_band()]
436+
).to_crs(self.crs())
437+
else:
438+
# Get WGS84 extent
439+
extent_wgs84 = self.wgs84_extent()
403440

404-
# Convert to UTM
405-
return extent_wgs84.to_crs(self.crs())
441+
# Convert to UTM
442+
return extent_wgs84.to_crs(self.crs())
406443

407444
@cache
408445
def crs(self) -> crs.CRS:
@@ -420,11 +457,17 @@ def crs(self) -> crs.CRS:
420457
Returns:
421458
crs.CRS: CRS object
422459
"""
423-
# Get WGS84 extent
424-
extent_wgs84 = self.wgs84_extent()
460+
if self.is_ortho:
461+
with rasterio.open(
462+
str(self.get_raw_band_paths()[self.get_default_band()])
463+
) as ds:
464+
return ds.crs
465+
else:
466+
# Get WGS84 extent
467+
extent_wgs84 = self.wgs84_extent()
425468

426-
# Estimate UTM from extent
427-
return extent_wgs84.estimate_utm_crs()
469+
# Estimate UTM from extent
470+
return extent_wgs84.estimate_utm_crs()
428471

429472
@abstractmethod
430473
def _set_sensor_mode(self) -> None:

eoreader/products/sar/tsx_product.py

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626
import geopandas as gpd
2727
import rasterio
2828
from lxml import etree
29-
from rasterio import crs
30-
from sertit import path, rasters, vectors
29+
from sertit import path, vectors
3130
from sertit.misc import ListEnum
3231
from sertit.types import AnyPathStrType
3332

@@ -346,51 +345,6 @@ def _post_init(self, **kwargs) -> None:
346345
# Post init done by the super class
347346
super()._post_init(**kwargs)
348347

349-
@cache
350-
def extent(self) -> gpd.GeoDataFrame:
351-
"""
352-
Get UTM extent of the tile
353-
354-
.. code-block:: python
355-
356-
>>> from eoreader.reader import Reader
357-
>>> path = r"S1A_IW_GRDH_1SDV_20191215T060906_20191215T060931_030355_0378F7_3696.zip"
358-
>>> prod = Reader().open(path)
359-
>>> prod.utm_extent()
360-
Name ... geometry
361-
0 Sentinel-1 Image Overlay ... POLYGON ((817914.501 4684349.823, 555708.624 4...
362-
[1 rows x 12 columns]
363-
364-
Returns:
365-
gpd.GeoDataFrame: Extent in UTM
366-
"""
367-
if self.product_type == TsxProductType.EEC:
368-
return rasters.get_extent(self.get_default_band_path()).to_crs(self.crs())
369-
else:
370-
return super().extent()
371-
372-
@cache
373-
def crs(self) -> crs.CRS:
374-
"""
375-
Get UTM projection
376-
377-
.. code-block:: python
378-
379-
>>> from eoreader.reader import Reader
380-
>>> path = r"S1A_IW_GRDH_1SDV_20191215T060906_20191215T060931_030355_0378F7_3696.zip"
381-
>>> prod = Reader().open(path)
382-
>>> prod.utm_crs()
383-
CRS.from_epsg(32630)
384-
385-
Returns:
386-
crs.CRS: CRS object
387-
"""
388-
if self.product_type == TsxProductType.EEC:
389-
with rasterio.open(str(self.get_default_band_path())) as ds:
390-
return ds.crs
391-
else:
392-
return super().crs()
393-
394348
@cache
395349
def wgs84_extent(self) -> gpd.GeoDataFrame:
396350
"""

0 commit comments

Comments
 (0)