def subset_image_by_shapefile(imagefile, shapefile, bkeepmidfile): """ subset an image by polygons contained in the shapefile Args: imagefile:input image file path shapefile:input shapefile contains polygon bkeepmidfile:indicate whether keep middle file Returns:output file name if succussful, False Otherwise """ if io_function.is_file_exist(imagefile) is False: return False if io_function.is_file_exist(shapefile) is False: return False Outfilename = io_function.get_name_by_adding_tail(imagefile, 'vsub') # ds = ogr.Open(shapefile) # lyr = ds.GetLayer(0) # lyr.ResetReading() # ft = lyr.GetNextFeature() # subprocess.call(['gdalwarp', imagefile, Outfilename, '-cutline', shapefile,\ # '-crop_to_cutline']) orgimg_obj = RSImageclass() if orgimg_obj.open(imagefile) is False: return False x_res = abs(orgimg_obj.GetXresolution()) y_res = abs(orgimg_obj.GetYresolution()) CommandString = 'gdalwarp ' + ' -tr ' + str(x_res) + ' ' + str( y_res ) + ' ' + imagefile + ' ' + Outfilename + ' -cutline ' + shapefile + ' -crop_to_cutline ' + ' -overwrite ' if basic.exec_command_string_one_file(CommandString, Outfilename) is False: return False # while ft: # country_name = ft.GetFieldAsString('admin') # outraster = imagefile.replace('.tif', '_%s.tif' % country_name.replace(' ', '_')) # subprocess.call(['gdalwarp', imagefile, Outfilename, '-cutline', shapefile, # '-crop_to_cutline', '-cwhere', "'admin'='%s'" % country_name]) # # ft = lyr.GetNextFeature() if not bkeepmidfile: io_function.delete_file_or_dir(imagefile) os.remove(imagefile) if io_function.is_file_exist(Outfilename): return Outfilename else: # basic.outputlogMessage(result) basic.outputlogMessage( 'The version of GDAL must be great than 2.0 in order to use the r option ' ) return False
def mosaics_images(raster_files, outputfile, nodata): """ mosaic a set of images. All the images must be in the same coordinate system and have a matching number of bands, Args: raster_files:a set of images with same coordinate system and have a matching number of bands, list type outputfile: the mosaic result file Returns: the result path if successful, False otherwise """ if isinstance(raster_files, list) is False: basic.outputlogMessage('the type of raster_files must be list') return False if len(raster_files) < 2: basic.outputlogMessage('file count less than 2') return False inputfile = '' for i in range(0, len(raster_files)): if io_function.is_file_exist(raster_files[i]) is False: return False inputfile = inputfile + ' ' + raster_files[i] CommandString = 'gdal_merge.py ' + inputfile + ' -o ' + outputfile + ' -n ' + str( nodata) return basic.exec_command_string_one_file(CommandString, outputfile)
def transforms_raster_srs(rasterfile,t_srs,t_file,x_res,y_res,resample_m='bilinear', o_format='GTiff',compress=None, tiled=None, bigtiff=None): """ convert raster file to target SRS(Spatial Reference System) Args: rasterfile:input raster file t_srs: target SRS(Spatial Reference System) t_file:the output target file x_res:set output file x-resolution (in target georeferenced units),assigning this value to make sure the resolution would not change in target file y_res:set output file y-resolution (in target georeferenced units),assigning this value to make sure the resolution would not change in target file Returns:the output file path is successful, False Otherwise """ if io_function.is_file_exist(rasterfile) is False: return False x_res = abs(x_res) y_res = abs(y_res) CommandString = 'gdalwarp -r %s -t_srs '%resample_m + t_srs +' -tr ' +str(x_res)+ ' ' + str(y_res) if compress != None: CommandString += ' -co ' + 'compress=%s'%compress # lzw if tiled != None: CommandString += ' -co ' + 'TILED=%s'%tiled # yes if bigtiff != None: CommandString += ' -co ' + 'bigtiff=%s' % bigtiff # IF_SAFER CommandString += ' ' + rasterfile + ' ' + t_file return basic.exec_command_string_one_file(CommandString,t_file)
def Read_Image_band_data_to_numpy_array_all_pixel(self,bandindex,image_path): if io_function.is_file_exist(image_path) is False: return False self.img__obj = RSImageclass() if self.img__obj.open(image_path) is False: return False width = self.img__obj.GetWidth() height = self.img__obj.GetHeight() return self.__Read_band_data_to_numpy_array(bandindex,0,0,width,height,self.img__obj)
def convert_image_to_gray(output_image,input_image,src_min,src_max,dst_min,dst_max): if io_function.is_file_exist(input_image) is False: return False src_min = str(src_min) src_max = str(src_max) dst_min = str(dst_min) dst_max = str(dst_max) CommandString = 'gdal_translate -r bilinear -ot Byte -scale ' + ' ' + src_min + ' ' + src_max + ' ' + dst_min + ' ' + dst_max \ + ' ' + input_image + ' ' + output_image return basic.exec_command_string_one_file(CommandString,output_image)
def resample_image(input_img,output_img,target_resolutionX,target_resolutionY,method): """ resample the input image with specific resolution and resample method :param input_img: path of input image :param output_img: path of the output image :param target_resolutionX: the X resolution of output image :param target_resolutionY: the Y resolution of output image :param method: resample method(same as gdal) : nearest,bilinear,cubic,cubicspline,lanczos,average,mode :return:True if successful, False Otherwise """ if io_function.is_file_exist(input_img) is False: return False args_list = ['gdalwarp','-r',method,'-tr',str(target_resolutionX),str(target_resolutionY),input_img,output_img] return basic.exec_command_args_list_one_file(args_list,output_img)
def Read_Image_data_to_numpy_array_all_band_pixel(self,image_path): if io_function.is_file_exist(image_path) is False: return False self.img__obj = RSImageclass() if self.img__obj.open(image_path) is False: return False width = self.img__obj.GetWidth() height = self.img__obj.GetHeight() bandcount = self.img__obj.GetBandCount() images = numpy.zeros((width, height, bandcount)) for band in range(0,bandcount): band_img = self.__Read_band_data_to_numpy_array(band+1,0,0,width,height,self.img__obj) if band_img is False: return False images[:,:,band] = band_img return images
def get_raster_or_vector_srs_info(spatial_data, format): """ get SRS(Spatial Reference System) information from raster or vector data Args: spatial_data: the path of raster or vector data format: Any of the usual GDAL/OGR forms(complete WKT, PROJ.4, EPSG:n or a file containing the SRS) Returns:the string of srs info in special format, False otherwise """ if io_function.is_file_exist(spatial_data) is False: return False CommandString = 'gdalsrsinfo -o ' + format + ' ' + spatial_data result = basic.exec_command_string_output_string(CommandString) if result.find('ERROR') >= 0: return False return result
def transforms_vector_srs(shapefile, t_srs, t_file): """ convert vector file to target SRS(Spatial Reference System) Args: shapefile:input vector file t_srs:target SRS(Spatial Reference System) t_file:the output target file Returns:the output file path is successful, False Otherwise """ if io_function.is_file_exist(shapefile) is False: return False CommandString = 'ogr2ogr -t_srs ' + t_srs + ' ' + t_file + ' ' + shapefile # if result.find('ERROR') >=0 or result.find('FAILURE'): # return False return basic.exec_command_string_one_file(CommandString, t_file)
def transforms_raster_srs_to_base_image(rasterfile,baseimage,target_file,x_res,y_res): """ convert raster file to target SRS(Spatial Reference System) of base image Args: rasterfile:input raster file baseimage:a image contains target srs info target_file:the output target file x_res:set output file x-resolution (in target georeferenced units) y_res:set output file y-resolution (in target georeferenced units) Returns:the output file path is successful, False Otherwise """ if io_function.is_file_exist(baseimage) is False: return False target_srs = get_raster_or_vector_srs_info_proj4(baseimage) if target_srs is False: return False return transforms_raster_srs(rasterfile,target_srs,target_file,x_res,y_res)
def transforms_raster_srs(rasterfile, t_srs, t_file, x_res, y_res): """ convert raster file to target SRS(Spatial Reference System) Args: rasterfile:input raster file t_srs: target SRS(Spatial Reference System) t_file:the output target file x_res:set output file x-resolution (in target georeferenced units),assigning this value to make sure the resolution would not change in target file y_res:set output file y-resolution (in target georeferenced units),assigning this value to make sure the resolution would not change in target file Returns:the output file path is successful, False Otherwise """ if io_function.is_file_exist(rasterfile) is False: return False x_res = abs(x_res) y_res = abs(y_res) CommandString = 'gdalwarp -r bilinear -t_srs ' + t_srs +' -tr ' +str(x_res)+ ' ' + str(y_res) \ +' '+ rasterfile +' '+ t_file return basic.exec_command_string_one_file(CommandString, t_file)
def phrase_xml(self): """ phrase xml file Returns:True if successful, False Otherwise """ meta_path = self.meta_path if io_function.is_file_exist(meta_path) is False: assert False try: self.tree = ET.parse(meta_path) self.root = self.tree.getroot() except ParseError: basic.outputlogMessage(str(ParseError)) basic.outputlogMessage('open %s failed' % meta_path) assert False if self.tree is None or self.root is None: basic.outputlogMessage('parse %s failed' % meta_path) assert False
def mosaics_images(raster_files, outputfile, nodata=None, compress=None, tiled=None, bigtiff=None): """ mosaic a set of images. All the images must be in the same coordinate system and have a matching number of bands, Args: raster_files:a set of images with same coordinate system and have a matching number of bands, list type outputfile: the mosaic result file Returns: the result path if successful, False otherwise """ if isinstance(raster_files, list) is False: basic.outputlogMessage('the type of raster_files must be list') return False if len(raster_files) < 2: basic.outputlogMessage('file count less than 2') return False inputfile = '' for i in range(0, len(raster_files)): if io_function.is_file_exist(raster_files[i]) is False: return False inputfile = inputfile + ' ' + raster_files[i] CommandString = 'gdal_merge.py ' + inputfile + ' -o ' + outputfile if nodata is not None: CommandString += ' -n ' + str(nodata) CommandString += ' -a_nodata ' + str(nodata) if compress != None: CommandString += ' -co ' + 'compress=%s' % compress # lzw if tiled != None: CommandString += ' -co ' + 'TILED=%s' % tiled # yes if bigtiff != None: CommandString += ' -co ' + 'bigtiff=%s' % bigtiff # IF_SAFER return basic.exec_command_string_one_file(CommandString, outputfile)
def main(options, args): input_path = args[0] if io_function.is_folder_exist(input_path) is True: if options.ext is None: basic.outputlogMessage('image file extenstion is need, type help for more information') return False file_list = io_function.get_file_list_by_ext(options.ext, input_path, bsub_folder=True) f_obj = open('images_list.txt','w') f_obj.writelines(["%s\n" % item for item in file_list]) f_obj.close() elif io_function.is_file_exist(input_path): f_obj = open(input_path,'r') file_list = f_obj.readlines() f_obj.close() else: basic.outputlogMessage('input error: %s'%input_path) return False for i in range(0,len(file_list)): file_list[i] = file_list[i].strip() return calculate_mean_of_images(file_list)
def compose_two_image(self, main_image, second_image, nodata): if io_function.is_file_exist(main_image) is False: return False if io_function.is_file_exist(second_image) is False: return False main_img = RSImageclass() if main_img.open(main_image) is False: return False width_main = main_img.GetWidth() height_main = main_img.GetHeight() bandcount_main = main_img.GetBandCount() sec_img = RSImageclass() if sec_img.open(second_image) is False: return False width_sec = sec_img.GetWidth() height_sec = sec_img.GetHeight() bandcount_sec = sec_img.GetBandCount() if width_main != width_sec or height_main != height_sec or bandcount_main != bandcount_sec: basic.outputlogMessage( 'Error: The dimension of two composed images is different') return False if main_img.GetGDALDataType() != sec_img.GetGDALDataType( ) or main_img.GetGDALDataType() != 6: basic.outputlogMessage( 'Error: The Data type of two composed imagaes is different or is not float' ) return False outputfile = io_function.get_name_by_adding_tail(main_image, 'comp') imagenew = RSImageclass() width = width_main height = height_main if not imagenew.New(outputfile, width, height, bandcount_main, main_img.GetGDALDataType()): return False for i in range(0, bandcount_main): bandindex = i + 1 band_main_str = main_img.ReadbandData(bandindex, 0, 0, width, height, main_img.GetGDALDataType()) band_sec_str = sec_img.ReadbandData(bandindex, 0, 0, width, height, sec_img.GetGDALDataType()) band_main_data = struct.unpack('f' * width * height, band_main_str) band_main_numpy = numpy.asarray(band_main_data) band_sec_data = struct.unpack('f' * width * height, band_sec_str) band_sec_numpy = numpy.asarray(band_sec_data) compose_loc = numpy.where( (numpy.fabs(band_main_numpy - nodata) < 0.0001) & (numpy.fabs(band_sec_numpy - nodata) > 0.0001)) band_main_numpy[compose_loc] = band_sec_numpy[compose_loc] basic.outputlogMessage('outputfortest2: compose_loc_num = %d' % numpy.array(compose_loc).size) templist = band_main_numpy.tolist() band_composed_str = struct.pack('%sf' % width * height, *templist) if imagenew.WritebandData(bandindex, 0, 0, width, height, band_composed_str, imagenew.GetGDALDataType()) is False: return False imagenew.SetBandNoDataValue(bandindex, nodata) imagenew.SetGeoTransform(main_img.GetGeoTransform()) imagenew.SetProjection(main_img.GetProjection()) main_img = None sec_img = None imagenew = None return outputfile
def subset_image_by_shapefile(imagefile, shapefile, bkeepmidfile=True, overwrite=False, format='GTiff', save_path=None, resample_m='bilinear', src_nodata=None, dst_nondata=None, xres=None, yres=None, compress=None, tiled=None, bigtiff=None, thread_num=None): """ subset an image by polygons contained in the shapefile the shapefile and imagefile may have different projections, the gdalwarp can handle Args: imagefile:input image file path shapefile:input shapefile contains polygon bkeepmidfile:indicate whether keep middle file format: output format, default is GTiff, GeoTIFF File Format. Use "VRT": GDAL Virtual Format to save disk storage Returns:output file name if succussful, False Otherwise """ if io_function.is_file_exist(imagefile) is False: return False if io_function.is_file_exist(shapefile) is False: return False if save_path is None: Outfilename = io_function.get_name_by_adding_tail(imagefile, 'vsub') else: Outfilename = save_path # ds = ogr.Open(shapefile) # lyr = ds.GetLayer(0) # lyr.ResetReading() # ft = lyr.GetNextFeature() # subprocess.call(['gdalwarp', imagefile, Outfilename, '-cutline', shapefile,\ # '-crop_to_cutline']) if overwrite is False and os.path.isfile(Outfilename): basic.outputlogMessage('warning, crop file: %s already exist, skip' % Outfilename) return Outfilename orgimg_obj = RSImageclass() if orgimg_obj.open(imagefile) is False: return False if xres is None or yres is None: x_res = abs(orgimg_obj.GetXresolution()) y_res = abs(orgimg_obj.GetYresolution()) else: x_res = xres y_res = yres CommandString = 'gdalwarp -r %s '% resample_m+' -tr ' + str(x_res) + ' '+ str(y_res)+ ' -of ' + format + ' ' + \ imagefile +' ' + Outfilename +' -cutline ' +shapefile +' -crop_to_cutline ' + ' -overwrite ' if src_nodata != None: CommandString += ' -srcnodata %d ' % src_nodata if dst_nondata != None: CommandString += ' -dstnodata %d ' % dst_nondata if compress != None: CommandString += ' -co ' + 'compress=%s' % compress # lzw if tiled != None: CommandString += ' -co ' + 'TILED=%s' % tiled # yes if bigtiff != None: CommandString += ' -co ' + 'bigtiff=%s' % bigtiff # IF_SAFER if thread_num != None: CommandString += ' -multi -wo NUM_THREADS=%d ' % thread_num if basic.exec_command_string_one_file(CommandString, Outfilename) is False: return False # while ft: # country_name = ft.GetFieldAsString('admin') # outraster = imagefile.replace('.tif', '_%s.tif' % country_name.replace(' ', '_')) # subprocess.call(['gdalwarp', imagefile, Outfilename, '-cutline', shapefile, # '-crop_to_cutline', '-cwhere', "'admin'='%s'" % country_name]) # # ft = lyr.GetNextFeature() if not bkeepmidfile: io_function.delete_file_or_dir(imagefile) os.remove(imagefile) if io_function.is_file_exist(Outfilename): return Outfilename else: # basic.outputlogMessage(result) basic.outputlogMessage( 'The version of GDAL must be great than 2.0 in order to use the r option ' ) return False
def convert_orthometricH_to_elliopsoidalH(output, orthometricH_file, geoidHfile): if io_function.is_file_exist( orthometricH_file) is False or io_function.is_file_exist( geoidHfile) is False: return False orthom_obj = RSImageclass() if orthom_obj.open(orthometricH_file) is False: return False geoidH_obj = RSImageclass() if geoidH_obj.open(geoidHfile) is False: return False Nodata = parameters.get_nodata_value() x_res = orthom_obj.GetXresolution() y_res = orthom_obj.GetYresolution() x_res_geoid = geoidH_obj.GetXresolution() y_res_geoid = geoidH_obj.GetYresolution() orthom_prj = orthom_obj.GetProjection() geoid_prj = geoidH_obj.GetProjection() #check projection and resolution, and convert it if need #use orthometricH_file as base image if x_res != x_res_geoid or y_res != y_res_geoid or orthom_prj != geoid_prj: geoid_convertfile = io_function.get_name_by_adding_tail( geoidHfile, 'tran') if os.path.isfile(geoid_convertfile) is False: if RSImageProcess.transforms_raster_srs( geoidHfile, orthom_prj, geoid_convertfile, abs(x_res), abs(y_res)) is False: return False else: basic.outputlogMessage(geoid_convertfile + ' already exist') #sub geoidHfile base on the small one (ulx, uly, lrx, lry) = RSImageProcess.get_image_proj_extent(orthometricH_file) if ulx is False: return False geoid_convertfile_sub = io_function.get_name_by_adding_tail( geoid_convertfile, 'sub') if os.path.isfile(geoid_convertfile_sub) is False: result = RSImageProcess.subset_image_projwin(geoid_convertfile_sub, geoid_convertfile, ulx, uly, lrx, lry) if result is False: return False else: basic.outputlogMessage(geoid_convertfile_sub + ' already exist') ##caculate elliopsoidal height # orthometricH_data = img_pro.Read_Image_band_data_to_numpy_array_all_pixel(1,orthometricH_file) # img_pro = None # img_pro = RSImgProclass(syslog) # geoidH_data = img_pro.Read_Image_band_data_to_numpy_array_all_pixel(1,geoid_convertfile_sub) # img_pro = None # if orthometricH_data.shape != geoidH_data.shape: # syslog.outputlogMessage("the shape of orthometricH_data and geoidH_data is different") # return False # # nodata = parameters.get_nodata_value(syslog) # width = orthom_obj.GetWidth() # height = orthom_obj.GetHeight() # orthometricH_data = orthometricH_data.astype(numpy.float32) # geoidH_data = geoidH_data.astype(numpy.float32) # elliopsoidalH = orthometricH_data + geoidH_data # elliopsoidalH = elliopsoidalH.reshape(height,width) # # RSImageProcess.save_numpy_2d_array_to_image_tif(output,elliopsoidalH,6,\ # orthom_obj.GetGeoTransform(),orthom_obj.GetProjection(),nodata,syslog) # # orthom_obj = None # geoidH_obj = None CommandString = 'gdal_calc.py -A '+orthometricH_file + ' -B ' + geoid_convertfile_sub +\ ' --NoDataValue='+str(Nodata) +' --outfile='+output + ' --calc="A+B"' if RSImageProcess.exec_commond_string_one_file(CommandString, output) is False: return False else: basic.outputlogMessage( "converting orthometric Height to elliopsoidal Height is completed" ) return True
def calculate_terrain_offset(output, dem_file, image_file, exec_dir, bkeepmidfile): if io_function.is_file_exist( image_file) is False or io_function.is_file_exist( dem_file, ) is False: return False exefile = os.path.join(exec_dir, 'geometry_pro') nodata = parameters.get_nodata_value() (centre_lat, centre_lon) = RSImage.get_image_latlon_centre(image_file) if centre_lat is False or centre_lon is False: return False image_obj = RSImageclass() if image_obj.open(image_file) is False: return False dem_obj = RSImageclass() if dem_obj.open(dem_file) is False: return False x_res = image_obj.GetXresolution() y_res = image_obj.GetYresolution() x_res_dem = dem_obj.GetXresolution() y_res_dem = dem_obj.GetYresolution() image_prj = image_obj.GetProjection() dem_prj = dem_obj.GetProjection() #check projection and resolution, and convert it if need #use orthometricH_file as base image dem_convertedfile = io_function.get_name_by_adding_tail(dem_file, 'tran') if x_res != x_res_dem or y_res != y_res_dem or image_prj != dem_prj: if os.path.isfile(dem_convertedfile) is False: if map_projection.transforms_raster_srs( dem_file, image_prj, dem_convertedfile, abs(x_res), abs(y_res)) is False: return False if os.path.isfile(dem_convertedfile): dem_file = dem_convertedfile #sub dem file (ulx, uly, lrx, lry) = RSImage.get_image_proj_extent(image_file) if ulx is False: return False tail = os.path.splitext(os.path.basename(image_file))[0] dem_file_sub = io_function.get_name_by_adding_tail(dem_file, tail) if os.path.isfile(dem_file_sub) is False: if RSImageProcess.subset_image_projwin(dem_file_sub, dem_file, ulx, uly, lrx, lry) is False: return False #calculateing terrain contains a lot of I/O operations, the parallel computing will slow down it nblockwidth = 8000 nblcckheight = 8000 njobs = 1 logfile = 'cal_terrain_offset_log.txt' CommandString = exefile \ + ' -i ' + image_file + ' -d ' + dem_file_sub \ + ' -o ' + output + ' -n ' + str(nodata)\ + ' -w ' + str(nblockwidth) + ' -h ' + str(nblcckheight) + ' -j ' +str(njobs) \ + ' --centre_lat=' + str(centre_lat) \ + ' --logfile=' + logfile basic.outputlogMessage(CommandString) (status, result) = commands.getstatusoutput(CommandString) basic.outputlogMessage(result) if bkeepmidfile is False: # if os.path.isfile(dem_convertedfile): # io_function.delete_file_or_dir(dem_convertedfile) if os.path.isfile(dem_file_sub): io_function.delete_file_or_dir(dem_file_sub) if os.path.isfile(output): if os.path.getsize(output) > 0: return output else: basic.outputlogMessage('error: the size of file %s is 0' % os.path.basename(output)) return False else: return False