def test_mlooked_path(): path = 'geo_060619-061002.tif' assert mlooked_path(path, looks=2, crop_out=4) == \ 'geo_060619-061002_2rlks_4cr.tif' path = 'some/dir/geo_060619-061002.tif' assert mlooked_path(path, looks=4, crop_out=2) == \ 'some/dir/geo_060619-061002_4rlks_2cr.tif' path = 'some/dir/geo_060619-061002_4rlks.tif' assert mlooked_path(path, looks=4, crop_out=8) == \ 'some/dir/geo_060619-061002_4rlks_4rlks_8cr.tif'
def output(self): if warp_required(self.xlooks, self.ylooks, self.crop_opt): return luigi.LocalTarget( cf.mlooked_path(self.ifg.data_path, self.ylooks, self.crop_opt)) else: return []
def _warp(ifg, x_looks, y_looks, extents, resolution, thresh, crop_out, write_to_disk=True): """ Convenience function for calling GDAL functionality """ if x_looks != y_looks: raise ValueError('X and Y looks mismatch') # cut, average, resample the final output layers looks_path = cf.mlooked_path(ifg.data_path, y_looks, crop_out) # # Add missing/updated metadata to resampled ifg/DEM # new_lyr = type(ifg)(looks_path) # new_lyr.open(readonly=True) # # for non-DEMs, phase bands need extra metadata & conversions # if hasattr(new_lyr, "phase_band"): # # TODO: LOS conversion to vertical/horizontal (projection) # # TODO: push out to workflow # #if params.has_key(REPROJECTION_FLAG): # # reproject() driver_type = 'GTiff' if write_to_disk else 'MEM' resampled_data, out_ds = gdalwarp.crop_resample_average( input_tif=ifg.data_path, extents=extents, new_res=resolution, output_file=looks_path, thresh=thresh, out_driver_type=driver_type) if not write_to_disk: return resampled_data, out_ds
def test_multilooked_projection_same_as_geotiff(self): xlooks = ylooks = 1 prepare_ifgs(self.ifg_paths, MAXIMUM_CROP, xlooks, ylooks) mlooked_paths = [ mlooked_path(f, crop_out=MAXIMUM_CROP, looks=xlooks) for f in self.ifg_paths ] self.assert_projection_equal(self.ifg_paths + mlooked_paths)
def setUp(self): from tests.common import small_data_setup self.ifgs = small_data_setup() self.ifg_paths = [i.data_path for i in self.ifgs] prepare_ifgs(self.ifg_paths, crop_opt=1, xlooks=1, ylooks=1) looks_paths = [ mlooked_path(d, looks=1, crop_out=1) for d in self.ifg_paths ] self.ifgs_with_nan = [Ifg(i) for i in looks_paths] for ifg in self.ifgs_with_nan: ifg.open()
def warp(ifg, x_looks, y_looks, extents, resolution, thresh, crop_out, write_to_disc=True): """ Resamples 'ifg' and returns a new interferogram object. :param xlooks: Factor to scale X axis by, 5 is 5x smaller, 1 is no change :param ylooks: Factor to scale Y axis by, 5 is 5x smaller, 1 is no change :param extents: Georeferenced extents for new file: (xfirst, yfirst, xlast, ylast) :param resolution: [xres, yres] or None. Sets resolution output interferogram metadata. Use *None* if raster size is not being changed :param thresh: See thresh in prepare_ifgs() :param verbose: True to print gdalwarp output to stdout :param write_to_disc: Whether to write to disc during warp :return xxxx """ if x_looks != y_looks: raise ValueError('X and Y looks mismatch') # cut, average, resample the final output layers looks_path = cf.mlooked_path(ifg.data_path, y_looks, crop_out) # # Add missing/updated metadata to resampled ifg/DEM # new_lyr = type(ifg)(looks_path) # new_lyr.open(readonly=True) # # for non-DEMs, phase bands need extra metadata & conversions # if hasattr(new_lyr, "phase_band"): # # TODO: LOS conversion to vertical/horizontal (projection) # # TODO: push out to workflow # #if params.has_key(REPROJECTION_FLAG): # # reproject() driver_type = 'GTiff' if write_to_disc else 'MEM' resampled_data, out_ds = gdalwarp.crop_resample_average( input_tif=ifg.data_path, extents=extents, new_res=resolution, output_file=looks_path, thresh=thresh, out_driver_type=driver_type) if not write_to_disc: return resampled_data, out_ds
def test_same_size_multilooking(self): ifgs = same_exts_ifgs() ifg_data_paths = [d.data_path for d in ifgs] xlooks = ylooks = 2 prepare_ifgs(ifg_data_paths, ALREADY_SAME_SIZE, xlooks, ylooks) looks_paths = [ mlooked_path(d, looks=xlooks, crop_out=ALREADY_SAME_SIZE) for d in ifg_data_paths ] mlooked = [Ifg(i) for i in looks_paths] for m in mlooked: m.open() self.assertEqual(len(mlooked), 2) for ifg in mlooked: self.assertAlmostEqual(ifg.x_step, xlooks * self.xs) self.assertAlmostEqual(ifg.x_step, ylooks * self.xs)
def prepare_ifg(raster_path, xlooks, ylooks, exts, thresh, crop_opt, write_to_disk=True): """ Open, resample, crop and optionally save to disk an interferogram or DEM. Returns are only given if write_to_disk=False :param str raster_path: Raster file path name :param int xlooks: Number of multi-looks in x; 5 is 5 times smaller, 1 is no change :param int ylooks: Number of multi-looks in y :param tuple exts: Tuple of user defined georeferenced extents for new file: (xfirst, yfirst, xlast, ylast)cropping coordinates :param float thresh: see thresh in prepare_ifgs() :param int crop_opt: Crop option :param bool write_to_disk: Write new data to disk :return: resampled_data: output cropped and resampled image :rtype: ndarray :return: out_ds: destination gdal dataset object :rtype: gdal.Dataset """ do_multilook = xlooks > 1 or ylooks > 1 # resolution=None completes faster for non-multilooked layers in gdalwarp resolution = [None, None] raster = dem_or_ifg(raster_path) if not raster.is_open: raster.open() if do_multilook: resolution = [xlooks * raster.x_step, ylooks * raster.y_step] if not do_multilook and crop_opt == ALREADY_SAME_SIZE: renamed_path = \ cf.mlooked_path(raster.data_path, looks=xlooks, crop_out=crop_opt) shutil.copy(raster.data_path, renamed_path) # set metadata to indicated has been cropped and multilooked # copy file with mlooked path return _dummy_warp(renamed_path) return _warp(raster, xlooks, ylooks, exts, resolution, thresh, crop_opt, write_to_disk)
def prepare_ifg(raster_path, xlooks, ylooks, exts, thresh, crop_opt, write_to_disc=True): """ Resample and crop interferograms/dems. :param: raster_path: xxxxx :param: xlooks: xxxxx :param: ylooks: xxxxx :param: exts: xxxxx :param: thresh: xxxxx :param: crop_out: xxxxx :param: write_to_disc: xxxxx :return xxxx """ do_multilook = xlooks > 1 or ylooks > 1 # resolution=None completes faster for non-multilooked layers in gdalwarp resolution = [None, None] raster = dem_or_ifg(raster_path) if not raster.is_open: raster.open() if do_multilook: resolution = [xlooks * raster.x_step, ylooks * raster.y_step] if not do_multilook and crop_opt == ALREADY_SAME_SIZE: renamed_path = \ cf.mlooked_path(raster.data_path, looks=xlooks, crop_out=crop_opt) shutil.copy(raster.data_path, renamed_path) # set metadata to indicated has been cropped and multilooked # copy file with mlooked path return dummy_warp(renamed_path) return warp(raster, xlooks, ylooks, exts, resolution, thresh, crop_opt, write_to_disc)
def test_output_datatype(self): """Test resampling method using a scaling factor of 4""" scale = 4 # assumes square cells self.ifgs.append(DEM(SML_TEST_DEM_TIF)) self.ifg_paths = [i.data_path for i in self.ifgs] + [SML_TEST_DEM_TIF] cext = self._custom_extents_tuple() xlooks = ylooks = scale prepare_ifgs(self.ifg_paths, CUSTOM_CROP, xlooks, ylooks, thresh=1.0, user_exts=cext) for i in self.ifg_paths: mlooked_ifg = mlooked_path(i, xlooks, CUSTOM_CROP) ds1 = DEM(mlooked_ifg) ds1.open() ds2 = DEM(i) ds2.open() self.assertEqual( ds1.dataset.GetRasterBand(1).DataType, ds2.dataset.GetRasterBand(1).DataType) ds1 = ds2 = None
def warp_old(ifg, x_looks, y_looks, extents, resolution, thresh, crop_out, verbose, ret_ifg=True): """ Resamples 'ifg' and returns a new Ifg obj. :param xlooks: integer factor to scale X axis by, 5 is 5x smaller, 1 is no change. :param ylooks: as xlooks, but for Y axis :param extents: georeferenced extents for new file: (xfirst, yfirst, xlast, ylast) :param resolution: [xres, yres] or None. Sets resolution output Ifg metadata. Use *None* if raster size is not being changed. :param thresh: see thresh in prepare_ifgs(). :param verbose: True to print gdalwarp output to stdout """ # pylint: disable=too-many-locals if x_looks != y_looks: raise ValueError('X and Y looks mismatch') # dynamically build command for call to gdalwarp cmd = ["gdalwarp", "-overwrite", "-srcnodata", "None", "-te"] + extents if not verbose: cmd.append("-q") # It appears that before vrions 1.10 gdal-warp did not copy meta-data # ... so we need to. Get the keys from the input here if (sum((int(v) * i for v, i in zip(gdal.__version__.split('.')[:2], [10, 1]))) < 20): fl = ifg.data_path dat = gdal.Open(fl) md = {k: v for k, v in dat.GetMetadata().items()} else: md = None # HACK: if resampling, cut segment with gdalwarp & manually average tiles data = None if resolution[0]: data = _resample_ifg(ifg, cmd, x_looks, y_looks, thresh, md) cmd += ["-tr"] + [str(r) for r in resolution] # change res of final output # use GDAL to cut (and resample) the final output layers looks_path = cf.mlooked_path(ifg.data_path, y_looks, crop_out) cmd += [ifg.data_path, looks_path] check_call(cmd) # now write the metadata from the input to the output if md is not None: new_lyr = gdal.Open(looks_path) for k, v in md.iteritems(): new_lyr.SetMetadataItem(k, v) # Add missing/updated metadata to resampled ifg/DEM new_lyr = type(ifg)(looks_path) new_lyr.open(readonly=False) # for non-DEMs, phase bands need extra metadata & conversions if hasattr(new_lyr, "phase_band"): if data is None: # data wasn't resampled, so flag incoherent cells data = new_lyr.phase_band.ReadAsArray() data = np.where(np.isclose(data, 0.0, atol=1e-6), np.nan, data) # TODO: LOS conversion to vertical/horizontal (projection) # TODO: push out to workflow #if params.has_key(REPROJECTION_FLAG): # reproject() # tricky: write either resampled or the basic cropped data to new layer new_lyr.phase_band.SetNoDataValue(nan) new_lyr.phase_band.WriteArray(data) new_lyr.nan_converted = True if ret_ifg: return data, looks_path else: return