PlaProduct
PlaProduct#
- class PlaProduct(product_path: Union[str, cloudpathlib.cloudpath.CloudPath, Path], archive_path: Optional[Union[str, cloudpathlib.cloudpath.CloudPath, Path]] = None, output_path: Optional[Union[str, cloudpathlib.cloudpath.CloudPath, Path]] = None, remove_tmp: bool = False, **kwargs)[source]#
Bases:
eoreader.products.optical.optical_product.OpticalProduct
Class of PlanetScope products. See here for more information.
The scaling factor to retrieve the calibrated radiance is 0.01.
- __init__(product_path: Union[str, cloudpathlib.cloudpath.CloudPath, Path], archive_path: Optional[Union[str, cloudpathlib.cloudpath.CloudPath, Path]] = None, output_path: Optional[Union[str, cloudpathlib.cloudpath.CloudPath, Path]] = None, remove_tmp: bool = False, **kwargs) None #
- clean_tmp()#
Clean the temporary directory of the current product
- clear()#
Clear this product’s cache
- get_band_paths(band_list: list, resolution: Optional[float] = None, **kwargs) dict [source]#
Return the paths of required bands.
>>> from eoreader.reader import Reader >>> from eoreader.bands import * >>> path = r"SENTINEL2A_20190625-105728-756_L2A_T31UEQ_C_V2-2" >>> prod = Reader().open(path) >>> prod.get_band_paths([GREEN, RED]) { <OpticalBandNames.GREEN: 'GREEN'>: 'SENTINEL2A_20190625-105728-756_L2A_T31UEQ_C_V2-2/SENTINEL2A_20190625-105728-756_L2A_T31UEQ_C_V2-2_FRE_B3.tif', <OpticalBandNames.RED: 'RED'>: 'SENTINEL2A_20190625-105728-756_L2A_T31UEQ_C_V2-2/SENTINEL2A_20190625-105728-756_L2A_T31UEQ_C_V2-2_FRE_B4.tif' }
- get_date(as_date: bool = False) Union[str, date] #
Get the product’s acquisition date.
>>> from eoreader.reader import Reader >>> path = r"S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip" >>> prod = Reader().open(path) >>> prod.get_date(as_date=True) datetime.datetime(2020, 8, 24, 0, 0) >>> prod.get_date(as_date=False) '20200824'
- get_datetime(as_datetime: bool = False) Union[str, datetime] [source]#
Get the product’s acquisition datetime, with format
YYYYMMDDTHHMMSS
<->%Y%m%dT%H%M%S
>>> from eoreader.reader import Reader >>> path = r"SENTINEL2A_20190625-105728-756_L2A_T31UEQ_C_V2-2" >>> prod = Reader().open(path) >>> prod.get_datetime(as_datetime=True) datetime.datetime(2019, 6, 25, 10, 57, 28, 756000), fetched from metadata, so we have the ms >>> prod.get_datetime(as_datetime=False) '20190625T105728'
- get_default_band() BandNames #
Get default band:
GREEN
for optical data as every optical satellite has a GREEN band.>>> from eoreader.reader import Reader >>> path = r"S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip" >>> prod = Reader().open(path) >>> prod.get_default_band() <OpticalBandNames.GREEN: 'GREEN'>
- Returns
Default band
- Return type
- get_default_band_path(**kwargs) Union[cloudpathlib.cloudpath.CloudPath, Path] #
Get default band (
GREEN
for optical data) path.>>> from eoreader.reader import Reader >>> path = r"S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip" >>> prod = Reader().open(path) >>> prod.get_default_band_path() 'zip+file://S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip!/S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE/GRANULE/L1C_T30TTK_A027018_20200824T111345/IMG_DATA/T30TTK_20200824T110631_B03.jp2'
- Parameters
kwargs – Additional arguments
- Returns
Default band path
- Return type
Union[CloudPath, Path]
- get_existing_band_paths() dict #
Return the existing band paths.
>>> from eoreader.reader import Reader >>> path = r"S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip" >>> prod = Reader().open(path) >>> prod.get_existing_band_paths() { <OpticalBandNames.CA: 'COASTAL_AEROSOL'>: 'zip+file://S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip!/S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE/GRANULE/L1C_T30TTK_A027018_20200824T111345/IMG_DATA/T30TTK_20200824T110631_B01.jp2', ..., <OpticalBandNames.SWIR_2: 'SWIR_2'>: 'zip+file://S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip!/S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE/GRANULE/L1C_T30TTK_A027018_20200824T111345/IMG_DATA/T30TTK_20200824T110631_B12.jp2' }
- Returns
Dictionary containing the path of each queried band
- Return type
- get_existing_bands() list #
Return the existing band paths.
>>> from eoreader.reader import Reader >>> path = r"S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip" >>> prod = Reader().open(path) >>> prod.get_existing_bands() [<OpticalBandNames.CA: 'COASTAL_AEROSOL'>, <OpticalBandNames.BLUE: 'BLUE'>, <OpticalBandNames.GREEN: 'GREEN'>, <OpticalBandNames.RED: 'RED'>, <OpticalBandNames.VRE_1: 'VEGETATION_RED_EDGE_1'>, <OpticalBandNames.VRE_2: 'VEGETATION_RED_EDGE_2'>, <OpticalBandNames.VRE_3: 'VEGETATION_RED_EDGE_3'>, <OpticalBandNames.NIR: 'NIR'>, <OpticalBandNames.NNIR: 'NARROW_NIR'>, <OpticalBandNames.WV: 'WATER_VAPOUR'>, <OpticalBandNames.CIRRUS: 'CIRRUS'>, <OpticalBandNames.SWIR_1: 'SWIR_1'>, <OpticalBandNames.SWIR_2: 'SWIR_2'>]
- Returns
List of existing bands in the products
- Return type
- get_quicklook_path() Union[None, str] #
Get quicklook path if existing (no such thing for Sentinel-2)
- Returns
Quicklook path
- Return type
- has_band(band: Union[BandNames, Callable]) bool #
Does this products has the specified band ?
By band, we mean:
satellite band
index
DEM band
cloud band
>>> from eoreader.reader import Reader >>> from eoreader.bands import * >>> path = r"S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip" >>> prod = Reader().open(path) >>> prod.has_band(GREEN) True >>> prod.has_band(TIR_2) False >>> prod.has_band(NDVI) True >>> prod.has_band(SHADOWS) False >>> prod.has_band(HILLSHADE) True
- has_bands(bands: Union[list, BandNames, Callable]) bool #
Does this products has the specified bands ?
By band, we mean:
satellite band
index
DEM band
cloud band
See
has_bands
for a code example.
- load(bands: Union[list, BandNames, Callable], resolution: Optional[float] = None, size: Optional[Union[list, tuple]] = None, **kwargs) dict #
Open the bands and compute the wanted index.
The bands will be purged of nodata and invalid pixels, the nodata will be set to 0 and the bands will be masked arrays in float.
Bands that come out this function at the same time are collocated and therefore have the same shapes. This can be broken if you load data separately. Its is best to always load DEM data with some real bands.
>>> from eoreader.reader import Reader >>> from eoreader.bands import * >>> path = r"S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip" >>> prod = Reader().open(path) >>> bands = prod.load([GREEN, NDVI], resolution=20) >>> bands { <function NDVI at 0x000001EFFFF5DD08>: <xarray.DataArray 'NDVI' (band: 1, y: 5490, x: 5490)> array([[[0.949506 , 0.92181516, 0.9279379 , ..., 1.8002278 , 1.5424857 , 1.6747767 ], [0.95369846, 0.91685396, 0.8957871 , ..., 1.5847116 , 1.5248713 , 1.5011379 ], [2.9928885 , 1.3031474 , 1.0076253 , ..., 1.5969834 , 1.5590671 , 1.5018653 ], ..., [1.4245619 , 1.6115025 , 1.6201663 , ..., 1.2387121 , 1.4025431 , 1.800678 ], [1.5627214 , 1.822388 , 1.7245892 , ..., 1.1694248 , 1.2573677 , 1.5767351 ], [1.653781 , 1.6424649 , 1.5923225 , ..., 1.3072611 , 1.2181134 , 1.2478763 ]]], dtype=float32) Coordinates: * band (band) int32 1 * y (y) float64 4.5e+06 4.5e+06 4.5e+06 ... 4.39e+06 4.39e+06 * x (x) float64 2e+05 2e+05 2e+05 ... 3.097e+05 3.098e+05 3.098e+05 spatial_ref int32 0, <OpticalBandNames.GREEN: 'GREEN'>: <xarray.DataArray (band: 1, y: 5490, x: 5490)> array([[[0.0615 , 0.061625, 0.061 , ..., 0.12085 , 0.120225, 0.113575], [0.061075, 0.06045 , 0.06025 , ..., 0.114625, 0.119625, 0.117625], [0.06475 , 0.06145 , 0.060925, ..., 0.111475, 0.114925, 0.115175], ..., [0.1516 , 0.14195 , 0.1391 , ..., 0.159975, 0.14145 , 0.127075], [0.140325, 0.125975, 0.131875, ..., 0.18245 , 0.1565 , 0.13015 ], [0.133475, 0.1341 , 0.13345 , ..., 0.15565 , 0.170675, 0.16405 ]]], dtype=float32) Coordinates: * band (band) int32 1 * y (y) float64 4.5e+06 4.5e+06 4.5e+06 ... 4.39e+06 4.39e+06 * x (x) float64 2e+05 2e+05 2e+05 ... 3.097e+05 3.098e+05 3.098e+05 spatial_ref int32 0 }
- Parameters
- Returns
{band_name, band xarray}
- Return type
- open_mask(mask_id: str, resolution: Optional[float] = None, size: Optional[Union[list, tuple]] = None) Optional[xarray.core.dataarray.DataArray] [source]#
Open a Planet UDM2 (Usable Data Mask) mask, band by band, as a xarray. Returns None if the mask is not available.
Do not open cloud mask with this function. Use
load
instead.See here for more information.
Accepted mask IDs:
CLEAR
: Band 1 Clear map [0, 1] 0: not clear, 1: clearSNOW
: Band 2 Snow map [0, 1] 0: no snow or ice, 1: snow or iceSHADOW
: Band 3 Shadow map [0, 1] 0: no shadow, 1: shadowLIGHT_HAZE
: Band 4 Light haze map [0, 1] 0: no light haze, 1: light hazeHEAVY_HAZE
: Band 5 Heavy haze map [0, 1] 0: no heavy haze, 1: heavy hazeCLOUD
: Band 6 Cloud map [0, 1] 0: no cloud, 1: cloudCONFIDENCE
: Band 7 Confidence map [0-100] %age value: per-pixel algorithmic confidence in classifUNUSABLE
: Band 8 Unusable pixels – Equivalent to the UDM asset
>>> from eoreader.bands import * >>> from eoreader.reader import Reader >>> path = r"SENTINEL2B_20190401-105726-885_L2A_T31UEQ_D_V2-0.zip" >>> prod = Reader().open(path) >>> prod.open_mask("EDG", GREEN) array([[[0, ..., 0]]], dtype=uint8)
- read_mtd()#
Read metadata and outputs the metadata XML root and its namespaces as a dict.
>>> from eoreader.reader import Reader >>> path = r"S1A_IW_GRDH_1SDV_20191215T060906_20191215T060931_030355_0378F7_3696.zip" >>> prod = Reader().open(path) >>> prod.read_mtd() (<Element product at 0x1832895d788>, '')
- Returns
Metadata XML root and its namespace
- Return type
(etree._Element, dict)
- stack(bands: list, resolution: Optional[float] = None, size: Optional[Union[list, tuple]] = None, stack_path: Optional[Union[str, cloudpathlib.cloudpath.CloudPath, Path]] = None, save_as_int: bool = False, **kwargs) xarray.core.dataarray.DataArray #
Stack bands and index of a products.
>>> from eoreader.reader import Reader >>> from eoreader.bands import * >>> path = r"S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip" >>> prod = Reader().open(path) >>> stack = prod.stack([NDVI, MNDWI, GREEN], resolution=20) # In meters >>> stack <xarray.DataArray 'NDVI_MNDWI_GREEN' (z: 3, y: 5490, x: 5490)> array([[[ 0.949506 , 0.92181516, 0.9279379 , ..., 1.8002278 , 1.5424857 , 1.6747767 ], [ 0.95369846, 0.91685396, 0.8957871 , ..., 1.5847116 , 1.5248713 , 1.5011379 ], [ 2.9928885 , 1.3031474 , 1.0076253 , ..., 1.5969834 , 1.5590671 , 1.5018653 ], ..., [ 1.4245619 , 1.6115025 , 1.6201663 , ..., 1.2387121 , 1.4025431 , 1.800678 ], [ 1.5627214 , 1.822388 , 1.7245892 , ..., 1.1694248 , 1.2573677 , 1.5767351 ], [ 1.653781 , 1.6424649 , 1.5923225 , ..., 1.3072611 , 1.2181134 , 1.2478763 ]], [[ 0.27066118, 0.23466069, 0.18792598, ..., -0.4611526 , -0.49751845, -0.4865216 ], [ 0.22425456, 0.28004232, 0.27851456, ..., -0.5032771 , -0.501796 , -0.502669 ], [-0.07466951, 0.06360884, 0.1207174 , ..., -0.50617427, -0.50219285, -0.5034222 ], [-0.47076276, -0.4705828 , -0.4747971 , ..., -0.32138503, -0.36619243, -0.37428448], [-0.4826967 , -0.5032287 , -0.48544118, ..., -0.278925 , -0.31404778, -0.36052078], [-0.488381 , -0.48253912, -0.4697526 , ..., -0.38105175, -0.30813277, -0.27739233]], [[ 0.0615 , 0.061625 , 0.061 , ..., 0.12085 , 0.120225 , 0.113575 ], [ 0.061075 , 0.06045 , 0.06025 , ..., 0.114625 , 0.119625 , 0.117625 ], [ 0.06475 , 0.06145 , 0.060925 , ..., 0.111475 , 0.114925 , 0.115175 ], ..., [ 0.1516 , 0.14195 , 0.1391 , ..., 0.159975 , 0.14145 , 0.127075 ], [ 0.140325 , 0.125975 , 0.131875 , ..., 0.18245 , 0.1565 , 0.13015 ], [ 0.133475 , 0.1341 , 0.13345 , ..., 0.15565 , 0.170675 , 0.16405 ]]], dtype=float32) Coordinates: * y (y) float64 4.5e+06 4.5e+06 4.5e+06 ... 4.39e+06 4.39e+06 * x (x) float64 2e+05 2e+05 2e+05 ... 3.097e+05 3.098e+05 3.098e+05 spatial_ref int32 0 * z (z) MultiIndex - variable (z) object 'NDVI' 'MNDWI' 'GREEN' - band (z) int64 1 1 1 -Attributes: long_name: ['NDVI', 'MNDWI', 'GREEN']
- Parameters
bands (list) – Bands and index combination
resolution (float) – Stack resolution. . If not specified, use the product resolution.
size (Union[tuple, list]) – Size of the array (width, height). Not used if resolution is provided.
stack_path (Union[str, CloudPath, Path]) – Stack path
save_as_int (bool) – Convert stack to uint16 to save disk space (and therefore multiply the values by 10.000)
**kwargs – Other arguments passed to
load
orrioxarray.to_raster()
(such ascompress
)
- Returns
Stack as a DataArray
- Return type
xr.DataArray
- archive_path#
Archive path, same as the product path if not specified. Useful when you want to know where both the extracted and archived version of your product are stored.
- band_names#
Band mapping between band wrapping names such as
GREEN
and band real number such as03
for Sentinel-2.
- condensed_name#
Condensed name, the filename with only useful data to keep the name unique (ie.
20191215T110441_S2_30TXP_L2A_122756
). Used to shorten names and paths.
- corresponding_ref#
The corresponding reference products to the current one (if the product is not a reference but has a reference data corresponding to it). A list because of multiple ref in case of non-stackable products (S3, S1…)
- crs = <methodtools._LruCacheWire object>#
- date#
Acquisition date.
- datetime#
Acquisition datetime.
- default_transform = <methodtools._LruCacheWire object>#
- extent = <methodtools._LruCacheWire object>#
- filename#
Product filename
- is_archived#
Is the archived product is processed (a products is considered as archived if its products path is a directory).
- is_reference#
If the product is a reference, used for algorithms that need pre and post data, such as fire detection.
- name#
Product true name (as specified in the metadata)
- needs_extraction#
Does this products needs to be extracted to be processed ? (
True
by default).
- nodata#
Product nodata, set to -9999 by default
- property output: Union[cloudpathlib.cloudpath.CloudPath, Path]#
Output directory of the product, to write orthorectified data for example.
- path#
Usable path to the product, either extracted or archived path, according to the satellite.
- platform#
Product platform, such as Sentinel-2
- product_type#
Product type, satellite-related field, such as L1C or L2A for Sentinel-2 data.
- resolution#
Default resolution in meters of the current product. For SAR product, we use Ground Range resolution as we will automatically orthorectify the tiles.
- sat_id#
Satellite ID, i.e.
S2
forSentinel-2
- sensor_type#
Sensor type, SAR or optical.
- split_name#
Split name, to retrieve every information from its true name (dates, tile, product type…).
- tile_name#
Tile if possible (for data that can be piled, for example S2 and Landsats).