def resample_setsm(raster, dstdir, args): for suffix in suffixes: srcdir, srcfn = os.path.split(raster) component = os.path.join(srcdir, srcfn.replace('dem.tif', suffix)) new_raster = os.path.join(dstdir, srcfn.replace('dem.tif', suffix)) if not os.path.isfile(new_raster): logger.info("Reprojecting {}".format(component)) #print new_raster if suffix == 'dem.tif': cmd = ( 'gdalwarp -q -tap -t_srs EPSG:{0} -tr {3} {3} -r bilinear -co tiled=yes -co compress=lzw ' '-co bigtiff=if_safer "{1}" "{2}"'.format( args.epsg, component, new_raster, args.resolution)) if not args.dryrun: taskhandler.exec_cmd(cmd) elif suffix == 'meta.txt': resample_stripmeta(component, new_raster, args.epsg) else: cmd = ( 'gdalwarp -q -tap -t_srs EPSG:{0} -tr {3} {3} -r near -co tiled=yes -co compress=lzw ' '-co bigtiff=if_safer "{1}" "{2}"'.format( args.epsg, component, new_raster, args.resolution)) if not args.dryrun: taskhandler.exec_cmd(cmd) logger.info('Done')
def resample_setsm(dem, args): low_res_dem = "{}.tif".format(os.path.splitext(dem)[0]) low_res_dem = os.path.join(os.path.dirname(low_res_dem),os.path.basename(low_res_dem.replace("_2m","_{}m".format(args.resolution)))) if not os.path.isfile(low_res_dem) or args.overwrite is True: logger.info("Resampling {}".format(dem)) #print low_res_dem resampling_method = 'bilinear' if args.component == 'dem' else 'near' cmd = 'gdalwarp -q -co tiled=yes -co compress=lzw -r {3} -tr {0} {0} "{1}" "{2}"'.format(args.resolution, dem, low_res_dem, resampling_method) #print cmd if not args.dryrun: taskhandler.exec_cmd(cmd)
def resample_setsm(dem, args): ext = get_extension(args.format) if args.dstdir: tempfile = "{}_temp.tif".format( os.path.join(args.dstdir, os.path.basename(os.path.splitext(dem)[0]))) low_res_dem = "{}_browse.{}".format( os.path.join(args.dstdir, os.path.basename(os.path.splitext(dem)[0])), ext) else: tempfile = "{}_temp.tif".format(os.path.splitext(dem)[0]) low_res_dem = "{}_browse.{}".format(os.path.splitext(dem)[0], ext) deletables = [] deletables.append(tempfile) if not os.path.isfile(low_res_dem) or args.overwrite is True: logger.info("Resampling {}".format(dem)) #print low_res_dem if args.component == 'dem': cmd = 'gdalwarp -tap -q -tr {0} {0} -r bilinear -dstnodata -9999 "{1}" "{2}"'.format( args.resolution, dem, tempfile) cmd2 = 'gdaldem hillshade -q -z 3 -compute_edges -of {2} -co TILED=YES -co BIGTIFF=IF_SAFER -co COMPRESS=LZW "{0}" "{1}"'.format( tempfile, low_res_dem, args.format) elif args.component == 'matchtag': cmd = 'gdal_translate -q -tr {0} {0} -of {3} -r near -a_nodata 0 "{1}" "{2}"'.format( args.resolution, dem, low_res_dem, args.format) cmd2 = None else: cmd = 'gdal_translate -tap -q -ot Byte -scale -tr {0} {0} -of {3} -r cubic -a_nodata 0 "{1}" "{2}"'.format( args.resolution, dem, low_res_dem, args.format) cmd2 = None #print cmd if not args.dryrun: taskhandler.exec_cmd(cmd) if cmd2: taskhandler.exec_cmd(cmd2) if not args.dryrun: for f in deletables: if os.path.isfile(f): try: os.remove(f) except: print "Cannot remove %s" % f
def resample_setsm(dem, args): low_res_dem = "{}_{}m.tif".format( os.path.splitext(dem)[0], args.resolution) if not os.path.isfile(low_res_dem) or args.overwrite is True: logger.info("Resampling {}".format(dem)) #print low_res_dem resampling_method = 'bilinear' if args.component == 'dem' else 'near' cmd = 'gdalwarp -q -co tiled=yes -co compress=lzw -r {3} -tr {0} {0} "{1}" "{2}"'.format( args.resolution, dem, low_res_dem, resampling_method) #print cmd if not args.dryrun: taskhandler.exec_cmd(cmd) if os.path.isfile(low_res_dem): cmd = 'gdaladdo -q "{}" 2 4 8 16'.format(low_res_dem) #print cmd if not args.dryrun: taskhandler.exec_cmd(cmd)
def main(): ######################################################### #### Handle args ######################################################### #### Set Up Arguments parser = argparse.ArgumentParser( description="Create mosaic subtile" ) parser.add_argument("tile", help="output tile name") parser.add_argument("src", help="textfile of input rasters (tif only)") parser.add_argument("-r", "--resolution", nargs=2, type=float, help="output pixel resolution -- xres yres (default is same as first input file)") parser.add_argument("-e", "--extent", nargs=4, type=float, help="extent of output mosaic -- xmin xmax ymin ymax (default is union of all inputs)") parser.add_argument("-t", "--tilesize", nargs=2, type=float, help="tile size in coordinate system units -- xsize ysize (default is 40,000 times output " "resolution)") parser.add_argument("--force-pan-to-multi", action="store_true", default=False, help="if output is multiband, force script to also use 1 band images") parser.add_argument("-b", "--bands", type=int, help="number of output bands( default is number of bands in the first image)") parser.add_argument("--median-remove", action="store_true", default=False, help="subtract the median from each input image before forming the mosaic in order to correct " "for contrast") parser.add_argument("--wd", help="scratch space (default is mosaic directory)") parser.add_argument("--gtiff-compression", choices=mosaic.GTIFF_COMPRESSIONS, default="lzw", help="GTiff compression type. Default=lzw ({})".format(','.join(mosaic.GTIFF_COMPRESSIONS))) parser.add_argument("--version", action='version', version="imagery_utils v{}".format(utils.package_version)) #### Parse Arguments args = parser.parse_args() status = 0 bands = args.bands inpath = args.src tile = args.tile ref_xres, ref_yres = args.resolution xmin, xmax, ymin, ymax = args.extent dims = "-tr {} {} -te {} {} {} {}".format(ref_xres, ref_yres, xmin, ymin, xmax, ymax) ##### Configure Logger logfile = os.path.splitext(tile)[0] + ".log" lfh = logging.FileHandler(logfile) lfh.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s %(levelname)s- %(message)s', '%m-%d-%Y %H:%M:%S') lfh.setFormatter(formatter) logger.addHandler(lfh) #### get working directory if args.wd: if os.path.isdir(args.wd): localpath = args.wd else: parser.error("scratch space directory does not exist: {0}".format(args.wd)) else: localpath = os.path.dirname(tile) intersects = [] if os.path.isfile(inpath): t = open(inpath, 'r') for line in t.readlines(): line = line.strip('\n').strip('\r') if ',' in line: image, median_string = line.split(',') iinfo = mosaic.ImageInfo(image, "IMAGE") median = {} for stat in median_string.split(";"): k, v = stat.split(":") median[int(k)] = float(v) if len(median) == iinfo.bands: iinfo.set_raster_median(median) else: logger.warning("Median dct length (%i) does not match band count (%i)", len(median), iinfo.bands) else: iinfo = mosaic.ImageInfo(line, "IMAGE") intersects.append(iinfo) t.close() else: logger.error("Intersecting image file does not exist: %i", inpath) logger.info(tile) logger.info("Number of image found in source file: %i", len(intersects)) wd = os.path.join(localpath, os.path.splitext(os.path.basename(tile))[0]) if not os.path.isdir(wd): os.makedirs(wd) localtile2 = os.path.join(wd, os.path.basename(tile)) localtile1 = localtile2.replace(".tif", "_temp.tif") del_images = [] images = {} #### Get Extent geometry poly_wkt = 'POLYGON (( {} {}, {} {}, {} {}, {} {}, {} {} ))'.format(xmin, ymin, xmin, ymax, xmax, ymax, xmax, ymin, xmin, ymin) c = 0 for iinfo in intersects: #### Check if bands number is correct mergefile = iinfo.srcfp if args.force_pan_to_multi and iinfo.bands > 1: if iinfo.bands == 1: mergefile = os.path.join(wd, os.path.basename(iinfo.srcfp)[:-4]) + "_merge.tif" cmd = 'gdal_merge.py -ps {} {} -separate -o "{}" "{}"'.format(ref_xres, ref_yres, mergefile, '" "'.join([iinfo.srcfp] * iinfo.bands)) taskhandler.exec_cmd(cmd) srcnodata = " ".join([str(ndv) for ndv in iinfo.nodatavalue]) if args.median_remove: dst = os.path.join(wd, os.path.basename(mergefile)[:-4]) + "_median_removed.tif" status = BandSubtractMedian(iinfo, dst) if status == 1: logger.error("BandSubtractMedian() failed on %s", mergefile) sys.exit(1) ds = gdal.Open(dst) if ds: srcnodata_val = ds.GetRasterBand(1).GetNoDataValue() srcnodata = " ".join([str(srcnodata_val)] * bands) mergefile = dst else: logger.error("BandSubtractMedian() failed at gdal.Open(%s)", dst) sys.exit(1) if c == 0: if os.path.isfile(localtile1): logger.info("localtile1 already exists") status = 1 break cmd = 'gdalwarp {} -srcnodata "{}" -dstnodata "{}" "{}" "{}"'.format(dims, srcnodata, srcnodata, mergefile, localtile1) taskhandler.exec_cmd(cmd) else: cmd = 'gdalwarp -srcnodata "{}" "{}" "{}"'.format(srcnodata, mergefile, localtile1) taskhandler.exec_cmd(cmd) c += 1 if not mergefile == iinfo.srcfp: del_images.append(mergefile) del_images.append(localtile1) if status == 0: #### Write to Compressed file if os.path.isfile(localtile1): if args.gtiff_compression == 'lzw': compress_option = '-co "compress=lzw"' elif args.gtiff_compression == 'jpeg95': compress_option = '-co "compress=jpeg" -co "jpeg_quality=95"' cmd = 'gdal_translate -stats -of GTiff {} -co "PHOTOMETRIC=MINISBLACK" -co "TILED=YES" -co ' \ '"BIGTIFF=IF_SAFER" "{}" "{}"'.format(compress_option, localtile1, localtile2) taskhandler.exec_cmd(cmd) #### Build Pyramids if os.path.isfile(localtile2): cmd = 'gdaladdo "{}" 2 4 8 16 30'.format(localtile2) taskhandler.exec_cmd(cmd) #### Copy tile to destination if os.path.isfile(localtile2): logger.info("Copying output files to destination dir") mosaic.copyall(localtile2, os.path.dirname(tile)) del_images.append(localtile2) #### Delete temp files utils.delete_temp_files(del_images) shutil.rmtree(wd) logger.info("Done")
def exec_pansharpen(image_pair, pansh_dstfp, args): dstdir = os.path.dirname(pansh_dstfp) #### Get working dir if args.wd is not None: wd = args.wd else: wd = dstdir if not os.path.isdir(wd): try: os.makedirs(wd) except OSError: pass logger.info("Working Dir: %s" % wd) #### Identify name pattern print "Multispectral image: %s" % image_pair.mul_srcfp print "Panchromatic image: %s" % image_pair.pan_srcfp if args.dem is not None: dem_arg = '-d "%s" ' % args.dem else: dem_arg = "" bittype = utils.get_bit_depth(args.outtype) pan_basename = os.path.splitext(image_pair.pan_srcfn)[0] mul_basename = os.path.splitext(image_pair.mul_srcfn)[0] pan_local_dstfp = os.path.join( wd, "{}_{}{}{}.tif".format(pan_basename, bittype, args.stretch, args.epsg)) mul_local_dstfp = os.path.join( wd, "{}_{}{}{}.tif".format(mul_basename, bittype, args.stretch, args.epsg)) pan_dstfp = os.path.join( dstdir, "{}_{}{}{}.tif".format(pan_basename, bittype, args.stretch, args.epsg)) mul_dstfp = os.path.join( dstdir, "{}_{}{}{}.tif".format(mul_basename, bittype, args.stretch, args.epsg)) pansh_tempfp = os.path.join( wd, "{}_{}{}{}_pansh_temp.tif".format(mul_basename, bittype, args.stretch, args.epsg)) pansh_local_dstfp = os.path.join( wd, "{}_{}{}{}_pansh.tif".format(mul_basename, bittype, args.stretch, args.epsg)) pansh_xmlfp = os.path.join( dstdir, "{}_{}{}{}_pansh.xml".format(mul_basename, bittype, args.stretch, args.epsg)) mul_xmlfp = os.path.join( dstdir, "{}_{}{}{}.xml".format(mul_basename, bittype, args.stretch, args.epsg)) if not os.path.isdir(wd): os.makedirs(wd) #### Ortho pan logger.info("Orthorectifying panchromatic image") if not os.path.isfile(pan_dstfp) and not os.path.isfile(pan_local_dstfp): ortho_functions.process_image(image_pair.pan_srcfp, pan_dstfp, args, image_pair.intersection_geom) if not os.path.isfile(pan_local_dstfp) and os.path.isfile(pan_dstfp): shutil.copy2(pan_dstfp, pan_local_dstfp) logger.info("Orthorectifying multispectral image") #### Ortho multi if not os.path.isfile(mul_dstfp) and not os.path.isfile(mul_local_dstfp): ## If resolution is specified in the command line, assume it's intended for the pansharpened image ## and multiply the multi by 4 if args.resolution: args.resolution = args.resolution * 4.0 ortho_functions.process_image(image_pair.mul_srcfp, mul_dstfp, args, image_pair.intersection_geom) if not os.path.isfile(mul_local_dstfp) and os.path.isfile(mul_dstfp): shutil.copy2(mul_dstfp, mul_local_dstfp) #### Pansharpen logger.info("Pansharpening multispectral image") if os.path.isfile(pan_local_dstfp) and os.path.isfile(mul_local_dstfp): if not os.path.isfile(pansh_local_dstfp): cmd = 'gdal_pansharpen.py -co BIGTIFF=IF_SAFER -co COMPRESS=LZW -co TILED=YES "{}" "{}" "{}"'.format( pan_local_dstfp, mul_local_dstfp, pansh_local_dstfp) taskhandler.exec_cmd(cmd) else: print "Pan or Multi warped image does not exist\n\t%s\n\t%s" % ( pan_local_dstfp, mul_local_dstfp) #### Make pyramids if os.path.isfile(pansh_local_dstfp): cmd = 'gdaladdo "%s" 2 4 8 16' % (pansh_local_dstfp) taskhandler.exec_cmd(cmd) ## Copy warped multispectral xml to pansharpened output shutil.copy2(mul_xmlfp, pansh_xmlfp) #### Copy pansharpened output if wd <> dstdir: for local_path, dst_path in [(pansh_local_dstfp, pansh_dstfp), (pan_local_dstfp, pan_dstfp), (mul_local_dstfp, mul_dstfp)]: if os.path.isfile(local_path) and not os.path.isfile(dst_path): shutil.copy2(local_path, dst_path) #### Delete Temp Files wd_files = [pansh_local_dstfp, pan_local_dstfp, mul_local_dstfp] if not args.save_temps: if wd <> dstdir: for f in wd_files: try: os.remove(f) except Exception, e: logger.warning('Could not remove %s: %s' % (os.path.basename(f), e))
def exec_pansharpen(image_pair, pansh_dstfp, args): dstdir = os.path.dirname(pansh_dstfp) #### Get working dir if args.wd is not None: wd = args.wd else: wd = dstdir if not os.path.isdir(wd): try: os.makedirs(wd) except OSError: pass logger.info("Working Dir: %s", wd) #### Identify name pattern print("Multispectral image: {}".format(image_pair.mul_srcfp)) print("Panchromatic image: {}".format(image_pair.pan_srcfp)) if args.dem is not None: dem_arg = '-d "{}" '.format(args.dem) else: dem_arg = "" bittype = utils.get_bit_depth(args.outtype) pan_basename = os.path.splitext(image_pair.pan_srcfn)[0] mul_basename = os.path.splitext(image_pair.mul_srcfn)[0] pan_local_dstfp = os.path.join(wd, "{}_{}{}{}.tif".format(pan_basename, bittype, args.stretch, args.epsg)) mul_local_dstfp = os.path.join(wd, "{}_{}{}{}.tif".format(mul_basename, bittype, args.stretch, args.epsg)) pan_dstfp = os.path.join(dstdir, "{}_{}{}{}.tif".format(pan_basename, bittype, args.stretch, args.epsg)) mul_dstfp = os.path.join(dstdir, "{}_{}{}{}.tif".format(mul_basename, bittype, args.stretch, args.epsg)) pansh_tempfp = os.path.join(wd, "{}_{}{}{}_pansh_temp.tif".format(mul_basename, bittype, args.stretch, args.epsg)) pansh_local_dstfp = os.path.join(wd, "{}_{}{}{}_pansh.tif".format(mul_basename, bittype, args.stretch, args.epsg)) pansh_xmlfp = os.path.join(dstdir, "{}_{}{}{}_pansh.xml".format(mul_basename, bittype, args.stretch, args.epsg)) mul_xmlfp = os.path.join(dstdir, "{}_{}{}{}.xml".format(mul_basename, bittype, args.stretch, args.epsg)) if not os.path.isdir(wd): os.makedirs(wd) #### Ortho pan logger.info("Orthorectifying panchromatic image") if not os.path.isfile(pan_dstfp) and not os.path.isfile(pan_local_dstfp): ortho_functions.process_image(image_pair.pan_srcfp, pan_dstfp, args, image_pair.intersection_geom) if not os.path.isfile(pan_local_dstfp) and os.path.isfile(pan_dstfp): shutil.copy2(pan_dstfp, pan_local_dstfp) logger.info("Orthorectifying multispectral image") #### Ortho multi if not os.path.isfile(mul_dstfp) and not os.path.isfile(mul_local_dstfp): ## If resolution is specified in the command line, assume it's intended for the pansharpened image ## and multiply the multi by 4 if args.resolution: args.resolution = args.resolution * 4.0 ortho_functions.process_image(image_pair.mul_srcfp, mul_dstfp, args, image_pair.intersection_geom) if not os.path.isfile(mul_local_dstfp) and os.path.isfile(mul_dstfp): shutil.copy2(mul_dstfp, mul_local_dstfp) #### Pansharpen ## get system info for program extension if platform.system() == 'Windows': py_ext = '' else: py_ext = '.py' logger.info("Pansharpening multispectral image") if os.path.isfile(pan_local_dstfp) and os.path.isfile(mul_local_dstfp): if not os.path.isfile(pansh_local_dstfp): cmd = 'gdal_pansharpen{} -co BIGTIFF=IF_SAFER -co COMPRESS=LZW -co TILED=YES "{}" "{}" "{}"'.\ format(py_ext, pan_local_dstfp, mul_local_dstfp, pansh_local_dstfp) taskhandler.exec_cmd(cmd) else: print("Pan or Multi warped image does not exist\n\t{}\n\t{}").format(pan_local_dstfp, mul_local_dstfp) #### Make pyramids if os.path.isfile(pansh_local_dstfp): cmd = 'gdaladdo -r {} "{}" 2 4 8 16'.format(args.pyramid_type, pansh_local_dstfp) taskhandler.exec_cmd(cmd) ## Copy warped multispectral xml to pansharpened output shutil.copy2(mul_xmlfp, pansh_xmlfp) #### Copy pansharpened output if wd != dstdir: for local_path, dst_path in [(pansh_local_dstfp, pansh_dstfp), (pan_local_dstfp, pan_dstfp), (mul_local_dstfp, mul_dstfp)]: if os.path.isfile(local_path) and not os.path.isfile(dst_path): shutil.copy2(local_path, dst_path) #### Delete Temp Files wd_files = [ pansh_local_dstfp, pan_local_dstfp, mul_local_dstfp ] if not args.save_temps: if wd != dstdir: for f in wd_files: try: os.remove(f) except Exception as e: logger.warning('Could not remove %s: %s', os.path.basename(f), e) if os.path.isfile(pansh_dstfp): return 0 else: return 0
def calc_ndvi(srcfp, dstfp, args): # ndvi nodata value ndvi_nodata = -9999 # tolerance for floating point equality tol = 0.00001 # get basenames for src and dst files, get xml metadata filenames srcdir, srcfn = os.path.split(srcfp) dstdir, dstfn = os.path.split(dstfp) bn, ext = os.path.splitext(srcfn) src_xml = os.path.join(srcdir, bn + '.xml') dst_xml = os.path.join(dstdir, bn + '_ndvi.xml') #### Get working dir if args.wd is not None: wd = args.wd else: wd = dstdir if not os.path.isdir(wd): try: os.makedirs(wd) except OSError: pass logger.info("Working Dir: %s", wd) print("Image: {}".format(srcfn)) ## copy source image to working directory srcfp_local = os.path.join(wd, srcfn) if not os.path.isfile(srcfp_local): shutil.copy2(srcfp, srcfp_local) ## open image and get band numbers ds = gdal.Open(srcfp_local) if ds: bands = ds.RasterCount if bands == 8: red_band_num = 5 nir_band_num = 7 elif bands == 4: red_band_num = 3 nir_band_num = 4 else: logger.error("Cannot calculate NDVI from a %i band image: %s", bands, srcfp_local) return 1 else: logger.error("Cannot open target image: %s", srcfp_local) return 1 ## check for input data type - must be float or int datatype = ds.GetRasterBand(1).DataType if datatype not in [1, 2, 3, 4, 5, 6, 7]: logger.error("Invalid input data type %s", datatype) return 1 ## get the raster dimensions nx = ds.RasterXSize ny = ds.RasterYSize ## open output file for write and copy proj/geotransform info if not os.path.isfile(dstfp): dstfp_local = os.path.join(wd, os.path.basename(dstfp)) gtiff_options = ['TILED=YES', 'COMPRESS=LZW', 'BIGTIFF=IF_SAFER'] driver = gdal.GetDriverByName('GTiff') out_ds = driver.Create(dstfp_local, nx, ny, 1, gdal.GetDataTypeByName(args.outtype), gtiff_options) if out_ds: out_ds.SetGeoTransform(ds.GetGeoTransform()) out_ds.SetProjection(ds.GetProjection()) ndvi_band = out_ds.GetRasterBand(1) ndvi_band.SetNoDataValue(float(ndvi_nodata)) else: logger.error("Couldn't open for write: %s", dstfp_local) return 1 ## for red and nir bands, get band data, nodata values, and natural block size ## if NoData is None default it to zero. red_band = ds.GetRasterBand(red_band_num) if red_band is None: logger.error("Can't load band %i from %s", red_band_num, srcfp_local) return 1 red_nodata = red_band.GetNoDataValue() if red_nodata is None: logger.info("Defaulting red band nodata to zero") red_nodata = 0.0 (red_xblocksize, red_yblocksize) = red_band.GetBlockSize() nir_band = ds.GetRasterBand(nir_band_num) if nir_band is None: logger.error("Can't load band %i from %s", nir_band_num, srcfp_local) return 1 nir_nodata = nir_band.GetNoDataValue() if nir_nodata is None: logger.info("Defaulting nir band nodata to zero") nir_nodata = 0.0 (nir_xblocksize, nir_yblocksize) = nir_band.GetBlockSize() ## if different block sizes choose the smaller of the two xblocksize = min([red_xblocksize, nir_xblocksize]) yblocksize = min([red_yblocksize, nir_yblocksize]) ## calculate the number of x and y blocks to read/write nxblocks = int(math.floor(nx + xblocksize - 1) / xblocksize) nyblocks = int(math.floor(ny + yblocksize - 1) / yblocksize) ## blocks loop yblockrange = range(nyblocks) xblockrange = range(nxblocks) for yblock in yblockrange: ## y offset for ReadAsArray yoff = yblock * yblocksize ## get block actual y size in case of partial block at edge if yblock < nyblocks - 1: block_ny = yblocksize else: block_ny = ny - (yblock * yblocksize) for xblock in xblockrange: ## x offset for ReadAsArray xoff = xblock * xblocksize ## get block actual x size in case of partial block at edge if xblock < (nxblocks - 1): block_nx = xblocksize else: block_nx = nx - (xblock * xblocksize) ## read a block from each band red_array = red_band.ReadAsArray(xoff, yoff, block_nx, block_ny) nir_array = nir_band.ReadAsArray(xoff, yoff, block_nx, block_ny) ## generate mask for red nodata, nir nodata, and ## (red+nir) less than tol away from zero red_mask = (red_array == red_nodata) if red_array[red_mask] != []: nir_mask = (nir_array == nir_nodata) if nir_array[nir_mask] != []: divzero_mask = abs(nir_array + red_array) < tol if red_array[divzero_mask] != []: ndvi_mask = red_mask | nir_mask | divzero_mask else: ndvi_mask = red_mask | nir_mask else: divzero_mask = abs(nir_array + red_array) < tol if red_array[divzero_mask] != []: ndvi_mask = red_mask | divzero_mask else: ndvi_mask = red_mask else: nir_mask = (nir_array == nir_nodata) if nir_array[nir_mask] != []: divzero_mask = abs(nir_array + red_array) < tol if red_array[divzero_mask] != []: ndvi_mask = nir_mask | divzero_mask else: ndvi_mask = nir_mask else: divzero_mask = abs(nir_array + red_array) < tol if red_array[divzero_mask] != []: ndvi_mask = divzero_mask else: ndvi_mask = numpy.full_like(red_array, fill_value=0, dtype=numpy.bool) ## declare ndvi array, init to nodata value ndvi_array = numpy.full_like(red_array, fill_value=ndvi_nodata, dtype=numpy.float32) ## cast bands to float for calc red_asfloat = numpy.array(red_array, dtype=numpy.float32) red_array = None nir_asfloat = numpy.array(nir_array, dtype=numpy.float32) nir_array = None ## calculate ndvi if ndvi_array[~ndvi_mask] != []: ndvi_array[~ndvi_mask] = numpy.divide(numpy.subtract(nir_asfloat[~ndvi_mask], red_asfloat[~ndvi_mask]), numpy.add(nir_asfloat[~ndvi_mask], red_asfloat[~ndvi_mask])) red_asfloat = None nir_asfloat = None ## scale and cast to int if outtype integer if args.outtype == 'Int16': ndvi_scaled = numpy.full_like(ndvi_array, fill_value=ndvi_nodata, dtype=numpy.int16) if ndvi_scaled[~ndvi_mask] != []: ndvi_scaled[~ndvi_mask] = numpy.array(ndvi_array[~ndvi_mask]*1000.0, dtype=numpy.int16) ndvi_array = ndvi_scaled ndvi_scaled = None ndvi_mask = None ## write valid portion of ndvi array to output file ndvi_band.WriteArray(ndvi_array, xoff, yoff) ndvi_array = None out_ds = None ds = None if os.path.isfile(dstfp_local): ## add pyramids cmd = 'gdaladdo "{}" 2 4 8 16'.format(dstfp_local) taskhandler.exec_cmd(cmd) ## copy to dst if wd != dstdir: shutil.copy2(dstfp_local, dstfp) ## copy xml to dst if os.path.isfile(src_xml): shutil.copy2(src_xml, dst_xml) else: logger.warning("xml %s not found", src_xml) ## Delete Temp Files temp_files = [srcfp_local] wd_files = [dstfp_local] if not args.save_temps: for f in temp_files: try: os.remove(f) except Exception as e: logger.warning('Could not remove %s: %s', os.path.basename(f), e) if wd != dstdir: for f in wd_files: try: os.remove(f) except Exception as e: logger.warning('Could not remove %s: %s', os.path.basename(f), e) else: logger.error("pgc_ndvi.py: %s was not created", dstfp_local) return 1 else: logger.info("pgc_ndvi.py: file %s already exists", dstfp) ## copy xml to dst if missing if not os.path.isfile(dst_xml): shutil.copy2(src_xml, dst_xml) return 0
def exec_pansharpen(image_pair, pansh_dstfp, args): dstdir = os.path.dirname(pansh_dstfp) #### Get working dir if args.wd is not None: wd = args.wd else: wd = dstdir if not os.path.isdir(wd): try: os.makedirs(wd) except OSError: pass logger.info("Working Dir: %s", wd) #### Identify name pattern print("Multispectral image: {}".format(image_pair.mul_srcfp)) print("Panchromatic image: {}".format(image_pair.pan_srcfp)) if args.dem is not None: dem_arg = '-d "{}" '.format(args.dem) else: dem_arg = "" bittype = utils.get_bit_depth(args.outtype) pan_basename = os.path.splitext(image_pair.pan_srcfn)[0] mul_basename = os.path.splitext(image_pair.mul_srcfn)[0] pan_local_dstfp = os.path.join( wd, "{}_{}{}{}.tif".format(pan_basename, bittype, args.stretch, args.epsg)) mul_local_dstfp = os.path.join( wd, "{}_{}{}{}.tif".format(mul_basename, bittype, args.stretch, args.epsg)) pan_dstfp = os.path.join( dstdir, "{}_{}{}{}.tif".format(pan_basename, bittype, args.stretch, args.epsg)) mul_dstfp = os.path.join( dstdir, "{}_{}{}{}.tif".format(mul_basename, bittype, args.stretch, args.epsg)) pansh_tempfp = os.path.join( wd, "{}_{}{}{}_pansh_temp.tif".format(mul_basename, bittype, args.stretch, args.epsg)) pansh_local_dstfp = os.path.join( wd, "{}_{}{}{}_pansh.tif".format(mul_basename, bittype, args.stretch, args.epsg)) pansh_xmlfp = os.path.join( dstdir, "{}_{}{}{}_pansh.xml".format(mul_basename, bittype, args.stretch, args.epsg)) mul_xmlfp = os.path.join( dstdir, "{}_{}{}{}.xml".format(mul_basename, bittype, args.stretch, args.epsg)) if not os.path.isdir(wd): os.makedirs(wd) #### Ortho pan logger.info("Orthorectifying panchromatic image") if not os.path.isfile(pan_dstfp) and not os.path.isfile(pan_local_dstfp): ortho_functions.process_image(image_pair.pan_srcfp, pan_dstfp, args, image_pair.intersection_geom) if not os.path.isfile(pan_local_dstfp) and os.path.isfile(pan_dstfp): shutil.copy2(pan_dstfp, pan_local_dstfp) logger.info("Orthorectifying multispectral image") #### Ortho multi if not os.path.isfile(mul_dstfp) and not os.path.isfile(mul_local_dstfp): ## If resolution is specified in the command line, assume it's intended for the pansharpened image ## and multiply the multi by 4 if args.resolution: args.resolution = args.resolution * 4.0 ortho_functions.process_image(image_pair.mul_srcfp, mul_dstfp, args, image_pair.intersection_geom) if not os.path.isfile(mul_local_dstfp) and os.path.isfile(mul_dstfp): shutil.copy2(mul_dstfp, mul_local_dstfp) #### Pansharpen ## get system info for program extension if platform.system() == 'Windows': py_ext = '' else: py_ext = '.py' pan_threading = '' if hasattr(args, 'threads'): if args.threads != 1: pan_threading = '-threads {}'.format(args.threads) logger.info("Pansharpening multispectral image") if os.path.isfile(pan_local_dstfp) and os.path.isfile(mul_local_dstfp): if not os.path.isfile(pansh_local_dstfp): cmd = 'gdal_pansharpen{} -co BIGTIFF=IF_SAFER -co COMPRESS=LZW -co TILED=YES {} "{}" "{}" "{}"'.\ format(py_ext, pan_threading, pan_local_dstfp, mul_local_dstfp, pansh_local_dstfp) taskhandler.exec_cmd(cmd) else: logger.warning( "Pan or Multi warped image does not exist\n\t{}\n\t{}".format( pan_local_dstfp, mul_local_dstfp)) #### Make pyramids if os.path.isfile(pansh_local_dstfp): cmd = 'gdaladdo -r {} "{}" 2 4 8 16'.format(args.pyramid_type, pansh_local_dstfp) taskhandler.exec_cmd(cmd) ## Copy warped multispectral xml to pansharpened output shutil.copy2(mul_xmlfp, pansh_xmlfp) #### Copy pansharpened output if wd != dstdir: for local_path, dst_path in [(pansh_local_dstfp, pansh_dstfp), (pan_local_dstfp, pan_dstfp), (mul_local_dstfp, mul_dstfp)]: if os.path.isfile(local_path) and not os.path.isfile(dst_path): shutil.copy2(local_path, dst_path) #### Delete Temp Files wd_files = [pansh_local_dstfp, pan_local_dstfp, mul_local_dstfp] if not args.save_temps: if wd != dstdir: for f in wd_files: try: os.remove(f) except Exception as e: logger.warning('Could not remove %s: %s', os.path.basename(f), e) if os.path.isfile(pansh_dstfp): return 0 else: return 0