def get_band_paths(self, band_list: list, resolution: float = None) -> dict: """ Return the paths of required bands. .. WARNING:: This functions orthorectifies SAR bands if not existing ! .. code-block:: python >>> from eoreader.reader import Reader >>> from eoreader.bands.alias import * >>> path = r"S1A_IW_GRDH_1SDV_20191215T060906_20191215T060931_030355_0378F7_3696.zip" >>> prod = Reader().open(path) >>> prod.get_band_paths([VV, HH]) { <SarBandNames.VV: 'VV'>: '20191215T060906_S1_IW_GRD\\20191215T060906_S1_IW_GRD_VV.tif' # HH doesn't exist } Args: band_list (list): List of the wanted bands resolution (float): Band resolution Returns: dict: Dictionary containing the path of each queried band """ band_paths = {} for band in band_list: bname = self.band_names[band] if bname is None: raise InvalidProductError( f"Non existing band ({band.name}) for {self.name}") try: # Try to load orthorectified bands band_paths[band] = files.get_file_in_dir( self._get_band_folder(), f"{self.condensed_name}_{bname}.tif", exact_name=True, ) except FileNotFoundError: speckle_band = sbn.corresponding_speckle(band) if speckle_band in self.pol_channels: if sbn.is_despeckle(band): # Despeckle the noisy band band_paths[band] = self._despeckle_sar(speckle_band) else: all_band_paths = self._pre_process_sar(resolution) band_paths = { band: path for band, path in all_band_paths.items() if band in band_list } return band_paths
def _pre_process_sar(self, resolution: float = None) -> dict: """ Pre-process SAR data (geocoding...) Args: resolution (float): Resolution Returns: dict: Dictionary containing {band: path} """ out = {} # Create target dir (tmp dir) with tempfile.TemporaryDirectory() as tmp_dir: # Set command as a list target_file = os.path.join(tmp_dir, f"{self.condensed_name}") # Use dimap for speed and security (ie. GeoTiff's broken georef) pp_target = f"{target_file}" pp_dim = pp_target + ".dim" # Pre-process graph if PP_GRAPH not in os.environ: sat = "s1" if self.sat_id == Platform.S1.name else "sar" spt = "grd" if self.sar_prod_type == SarProductType.GDRG else "cplx" pp_graph = os.path.join(utils.get_data_dir(), f"{spt}_{sat}_preprocess_default.xml") else: pp_graph = os.environ[PP_GRAPH] if not os.path.isfile(pp_graph) or not pp_graph.endswith( ".xml"): FileNotFoundError(f"{pp_graph} cannot be found.") # Command line if not os.path.isfile(pp_dim): def_res = float(os.environ.get(SAR_DEF_RES, self.resolution)) res_m = resolution if resolution else def_res res_deg = res_m / 10.0 * 8.983152841195215e-5 # Approx cmd_list = snap.get_gpt_cli( pp_graph, [ f"-Pfile={strings.to_cmd_string(self._snap_path)}", f"-Pout={pp_dim}", f"-Pcrs={self.crs()}", f"-Pres_m={res_m}", f"-Pres_deg={res_deg}", ], display_snap_opt=LOGGER.level == logging.DEBUG, ) # Pre-process SAR images according to the given graph LOGGER.debug("Pre-process SAR image") misc.run_cli(cmd_list) # Convert DIMAP images to GeoTiff for pol in self.pol_channels: # Speckle image out[sbn.from_value(pol)] = self._write_sar(pp_dim, pol.value) return out
def test_bands(): # SAR assert SarBandNames.from_list(["VV", "VH"]) == [VV, VH] assert SarBandNames.to_value_list([HV_DSPK, VV]) == ["HV_DSPK", "VV"] assert SarBandNames.to_value_list() == SarBandNames.list_values() assert SarBandNames.corresponding_speckle(SarBandNames.VV) == VV assert SarBandNames.corresponding_speckle(SarBandNames.VV_DSPK) == VV # OPTIC map_dic = { CA: "01", BLUE: "02", GREEN: "03", RED: "04", VRE_1: "05", VRE_2: "06", VRE_3: "07", NIR: "08", NARROW_NIR: "8A", WV: "09", SWIR_1: "11", SWIR_2: "12", } ob = OpticalBands() ob.map_bands(map_dic) for key, val in map_dic.items(): assert key in ob._band_map assert ob._band_map[key] == map_dic[key] with pytest.raises(InvalidTypeError): ob.map_bands({VV: "wrong_val"})
def get_existing_band_paths(self) -> dict: """ Return the existing orthorectified band paths (including despeckle bands). .. WARNING:: This functions orthorectifies SAR bands if not existing ! .. WARNING:: This functions despeckles SAR bands if not existing ! .. code-block:: python >>> from eoreader.reader import Reader >>> from eoreader.bands.alias import * >>> path = r"S1A_IW_GRDH_1SDV_20191215T060906_20191215T060931_030355_0378F7_3696.zip" >>> prod = Reader().open(path) >>> prod.get_existing_band_paths() Executing processing graph ....10%....20%....30%....40%....50%....60%....70%....80%....90% done. Executing processing graph ....10%....20%....30%....40%....50%....60%....70%....80%....90% done. { <SarBandNames.VV: 'VV'>: '20191215T060906_S1_IW_GRD\\20191215T060906_S1_IW_GRD_VV.tif', <SarBandNames.VH: 'VH'>: '20191215T060906_S1_IW_GRD\\20191215T060906_S1_IW_GRD_VH.tif', <SarBandNames.VV_DSPK: 'VV_DSPK'>: '20191215T060906_S1_IW_GRD\\20191215T060906_S1_IW_GRD_VV_DSPK.tif', <SarBandNames.VH_DSPK: 'VH_DSPK'>: '20191215T060906_S1_IW_GRD\\20191215T060906_S1_IW_GRD_VH_DSPK.tif' } Returns: dict: Dictionary containing the path of every orthorectified bands """ # Get raw bands (maximum number of bands) raw_bands = self._get_raw_bands() possible_bands = raw_bands + [ sbn.corresponding_despeckle(band) for band in raw_bands ] return self.get_band_paths(possible_bands)
def to_band(to_convert: list) -> list: """ Convert a string (or real value) to any alias, band or index. You can pass the name or the value of the bands. .. code-block:: python >>> to_band(["NDVI", "GREEN", RED, "VH_DSPK", "SLOPE", DEM, "CLOUDS", CLOUDS]) [<function NDVI at 0x00000154DDB12488>, <OpticalBandNames.GREEN: 'GREEN'>, <OpticalBandNames.RED: 'RED'>, <SarBandNames.VH_DSPK: 'VH_DSPK'>, <DemBandNames.SLOPE: 'SLOPE'>, <DemBandNames.DEM: 'DEM'>, <ClassifBandNames.CLOUDS: 'CLOUDS'>, <ClassifBandNames.CLOUDS: 'CLOUDS'>] Args: to_convert (list): Values to convert into band objects Returns: list: converted values """ if not isinstance(to_convert, list): to_convert = [to_convert] bands = [] for tc in to_convert: band_or_idx = None # Try legit types if isinstance(tc, str): # Try index if hasattr(_idx, tc): band_or_idx = getattr(_idx, tc) else: try: band_or_idx = _sbn.convert_from(tc)[0] except TypeError: try: band_or_idx = _obn.convert_from(tc)[0] except TypeError: try: band_or_idx = _dem.convert_from(tc)[0] except TypeError: try: band_or_idx = _clouds.convert_from(tc)[0] except TypeError: pass elif is_index(tc) or is_band(tc) or is_dem(tc) or is_clouds(tc): band_or_idx = tc # Store it if band_or_idx: bands.append(band_or_idx) else: raise InvalidTypeError(f"Unknown band or index: {tc}") return bands