def makeSRTM(scenes, srtmdir, outname): """ Create a DEM in Gamma format from SRTM tiles - coordinates are read to determine the required DEM extent and select the necessary hgt tiles - mosaics SRTM DEM tiles, converts them to Gamma format and subtracts offset to WGS84 ellipsoid intended for SRTM products downloaded from: - USGS: https://gdex.cr.usgs.gov/gdex/ - CGIAR: http://srtm.csi.cgiar.org Parameters ---------- scenes: list of str or pyroSAR.ID a list of Gamma parameter files or pyroSAR ID objects to read the DEM extent from srtmdir: str a directory containing the SRTM hgt tiles outname: str the name of the final DEM file Returns ------- """ tempdir = outname + '___temp' os.makedirs(tempdir) hgt_options = hgt(scenes) hgt_files = finder(srtmdir, hgt_options) nodatas = list(set([raster.Raster(x).nodata for x in hgt_files])) if len(nodatas) == 1: nodata = nodatas[0] else: raise RuntimeError('different nodata values are not permitted') srtm_vrt = os.path.join(tempdir, 'srtm.vrt') srtm_temp = srtm_vrt.replace('.vrt', '_tmp') srtm_final = srtm_vrt.replace('.vrt', '') gdalbuildvrt(hgt_files, srtm_vrt, {'srcNodata': nodata, 'options': ['-overwrite']}) gdal_translate(srtm_vrt, srtm_temp, {'format': 'ENVI', 'noData': nodata}) diff.srtm2dem(SRTM_DEM=srtm_temp, DEM=srtm_final, DEM_par=srtm_final + '.par', gflg=2, geoid='-', outdir=tempdir) shutil.move(srtm_final, outname) shutil.move(srtm_final + '.par', outname + '.par') par2hdr(outname + '.par', outname + '.hdr') shutil.rmtree(tempdir)
def test_auxil(tmpdir, testdata): dir = str(tmpdir) with Raster(testdata['tif']) as ras: bbox = os.path.join(dir, 'bbox.shp') ras.bbox(bbox) ogr2ogr(bbox, os.path.join(dir, 'bbox.gml'), {'format': 'GML'}) gdal_translate(ras.raster, os.path.join(dir, 'test'), {'format': 'ENVI'}) gdal_rasterize(bbox, os.path.join(dir, 'test2'), {'format': 'GTiff', 'xRes': 20, 'yRes': 20})
def test_stack(tmpdir, testdata): name = testdata['tif'] outname = os.path.join(str(tmpdir), 'test') tr = (30, 30) # no input files provided with pytest.raises(RuntimeError): stack(srcfiles=[], resampling='near', targetres=tr, srcnodata=-99, dstnodata=-99, dstfile=outname) # two files, but only one layer name with pytest.raises(RuntimeError): stack(srcfiles=[name, name], resampling='near', targetres=tr, srcnodata=-99, dstnodata=-99, dstfile=outname, layernames=['a']) # targetres must be a two-entry tuple/list with pytest.raises(RuntimeError): stack(srcfiles=[name, name], resampling='near', targetres=30, srcnodata=-99, dstnodata=-99, dstfile=outname) # only one file specified with pytest.raises(RuntimeError): stack(srcfiles=[name], resampling='near', targetres=tr, overwrite=True, srcnodata=-99, dstnodata=-99, dstfile=outname) # targetres must contain two values with pytest.raises(RuntimeError): stack(srcfiles=[name, name], resampling='near', targetres=(30, 30, 30), srcnodata=-99, dstnodata=-99, dstfile=outname) # unknown resampling method with pytest.raises(RuntimeError): stack(srcfiles=[name, name], resampling='foobar', targetres=tr, srcnodata=-99, dstnodata=-99, dstfile=outname) # non-existing files with pytest.raises(RuntimeError): stack(srcfiles=['foo', 'bar'], resampling='near', targetres=tr, srcnodata=-99, dstnodata=-99, dstfile=outname) # create a multi-band stack stack(srcfiles=[name, name], resampling='near', targetres=tr, overwrite=True, srcnodata=-99, dstnodata=-99, dstfile=outname, layernames=['test1', 'test2']) with Raster(outname) as ras: assert ras.bands == 2 # Raster.rescale currently only supports one band with pytest.raises(ValueError): ras.rescale(lambda x: x * 10) # outname exists and overwrite is False with pytest.raises(RuntimeError): stack(srcfiles=[name, name], resampling='near', targetres=tr, overwrite=False, srcnodata=-99, dstnodata=-99, dstfile=outname, layernames=['test1', 'test2']) # pass shapefile outname = os.path.join(str(tmpdir), 'test2') with Raster(name).bbox() as box: stack(srcfiles=[name, name], resampling='near', targetres=tr, overwrite=True, srcnodata=-99, dstnodata=-99, dstfile=outname, shapefile=box, layernames=['test1', 'test2']) with Raster(outname) as ras: assert ras.bands == 2 # pass shapefile and do mosaicing outname = os.path.join(str(tmpdir), 'test3') with Raster(name).bbox() as box: stack(srcfiles=[[name, name]], resampling='near', targetres=tr, overwrite=True, srcnodata=-99, dstnodata=-99, dstfile=outname, shapefile=box) with Raster(outname + '.tif') as ras: assert ras.bands == 1 assert ras.format == 'GTiff' # projection mismatch name2 = os.path.join(str(tmpdir), os.path.basename(name)) outname = os.path.join(str(tmpdir), 'test4') gdalwarp(name, name2, options={'dstSRS': crsConvert(4326, 'wkt')}) with pytest.raises(RuntimeError): stack(srcfiles=[name, name2], resampling='near', targetres=tr, overwrite=True, srcnodata=-99, dstnodata=-99, dstfile=outname) # no projection found outname = os.path.join(str(tmpdir), 'test5') gdal_translate(name, name2, {'options': ['-co', 'PROFILE=BASELINE']}) with Raster(name2) as ras: print(ras.projection) with pytest.raises(RuntimeError): stack(srcfiles=[name2, name2], resampling='near', targetres=tr, overwrite=True, srcnodata=-99, dstnodata=-99, dstfile=outname) # create separate GeoTiffs outdir = os.path.join(str(tmpdir), 'subdir') stack(srcfiles=[name, name], resampling='near', targetres=tr, overwrite=True, layernames=['test1', 'test2'], srcnodata=-99, dstnodata=-99, dstfile=outdir, separate=True, compress=True) # repeat with overwrite disabled (no error raised, just a print message) stack(srcfiles=[name, name], resampling='near', targetres=tr, overwrite=False, layernames=['test1', 'test2'], srcnodata=-99, dstnodata=-99, dstfile=outdir, separate=True, compress=True) # repeat without layernames but sortfun # bandnames not unique outdir = os.path.join(str(tmpdir), 'subdir2') with pytest.raises(RuntimeError): stack(srcfiles=[name, name], resampling='near', targetres=tr, overwrite=True, sortfun=os.path.basename, srcnodata=-99, dstnodata=-99, dstfile=outdir, separate=True, compress=True) # repeat without layernames but sortfun name2 = os.path.join(str(tmpdir), os.path.basename(name).replace('VV', 'XX')) shutil.copyfile(name, name2) outdir = os.path.join(str(tmpdir), 'subdir2') stack(srcfiles=[name, name2], resampling='near', targetres=tr, overwrite=True, sortfun=os.path.basename, srcnodata=-99, dstnodata=-99, dstfile=outdir, separate=True, compress=True) # shapefile filtering outdir = os.path.join(str(tmpdir), 'subdir3') files = [testdata['tif'], testdata['tif2'], testdata['tif3']] with Raster(files[0]).bbox() as box: stack(srcfiles=files, resampling='near', targetres=(30, 30), overwrite=False, layernames=['test1', 'test2', 'test3'], srcnodata=-99, dstnodata=-99, dstfile=outdir, separate=True, compress=True, shapefile=box) # repeated run with different scene selection and only one scene after spatial filtering stack(srcfiles=files[1:], resampling='near', targetres=(30, 30), overwrite=True, layernames=['test2', 'test3'], srcnodata=-99, dstnodata=-99, dstfile=outdir, separate=True, compress=True, shapefile=box)
def inc_stack(small, gamma, snap, outdir, prefix=''): outnames_base = ['small', 'gamma', 'snap'] outnames = [ os.path.join(outdir, prefix + x) + '.tif' for x in outnames_base ] if all([os.path.isfile(x) for x in outnames]): return outnames # set SMALL product nodata GeoTiff value with Raster(small)[0:100, 0:100] as ras: if ras.nodata is None: print('setting nodata value for SMALL product') mat = ras.matrix() nodata = float(mat[0, 0]) ras2 = gdal.Open(small, GA_Update) ras2.GetRasterBand(1).SetNoDataValue(nodata) ras2 = None tmpdir = os.path.join(outdir, 'tmp') if not os.path.isdir(tmpdir): os.makedirs(tmpdir) small_edit = os.path.join( tmpdir, os.path.basename(small).replace('.tif', '_edit.tif')) if not os.path.isfile(small_edit): print('reducing resolution of SMALL product') gdal_translate(small, small_edit, options={ 'xRes': 90, 'yRes': 90, 'resampleAlg': 'average', 'format': 'GTiff' }) # subtract 90 degrees from SMALL product small_out = outnames[0] if not os.path.isfile(small_out): print('subtracting 90 degrees from SMALL product') with Raster(small_edit) as ras: mat = ras.matrix() - 90 ras.assign(mat, 0) print('creating {}'.format(small_out)) ras.write(small_out, format='GTiff', nodata=-99) # set GAMMA product nodata value with Raster(gamma) as ras: if ras.nodata != 0: print('setting nodata value of GAMMA product') ras2 = gdal.Open(gamma, GA_Update) ras2.GetRasterBand(1).SetNoDataValue(0) ras2 = None # convert GAMMA product from radians to degrees gamma_deg = os.path.join( tmpdir, os.path.basename(gamma).replace('.tif', '_deg.tif')) if not os.path.isfile(gamma_deg): print('converting GAMMA product from radians to degrees') with Raster(gamma) as ras: mat = np.rad2deg(ras.matrix()) ras.assign(mat, 0) ras.write(gamma_deg, format='GTiff') gamma = gamma_deg # use extent of SMALL product as reference ext = Raster(small_out).bbox().extent # create new directory for the stacked files if not os.path.isdir(outdir): os.makedirs(outdir) # warp the products to their common extent warp_opts = { 'options': ['-q'], 'format': 'GTiff', 'multithread': True, 'outputBounds': (ext['xmin'], ext['ymin'], ext['xmax'], ext['ymax']), 'dstNodata': -99, 'xRes': 90, 'yRes': 90, 'resampleAlg': 'bilinear', 'dstSRS': 'EPSG:32632' } for i, item in enumerate([gamma, snap]): outfile = outnames[i + 1] if not os.path.isfile(outfile): print('creating {}'.format(outfile)) gdalwarp(src=item, dst=outfile, options=warp_opts) shutil.rmtree(tmpdir) return outnames