def read_tif(inputfile, band): tifObj = GeoTiffFile(inputfile) tifObj.readTif() data = tifObj.getBandData(band) width = tifObj.getWidth() height = tifObj.getHeight() proj = tifObj.getProj() geotrans = tifObj.getGeoTrans() return data, width, height, proj, geotrans
def delete3(): pass tif_path1 = r'E:\NPP\temp\svi01.tif' lat_path = r'E:\NPP\temp\Latitude.tif' lon_path = r'E:\NPP\temp\Longitude.tif' tif_obj1 = GeoTiffFile(lat_path) tif_obj1.readTif() lat_data = tif_obj1.getBandData(0) tif_obj2 = GeoTiffFile(lon_path) tif_obj2.readTif() lon_data = tif_obj2.getBandData(0) dataset = gdal.Open(tif_path1, gdal.GA_Update) geo_line = 7680 # 地理信息行数 geo_sample = 6400 # 地理信息列数 # 采样间隔 resample_step = 100 resample_line_num = int(geo_line / resample_step) resample_sample_num = int(geo_sample / resample_step) position_list = [] for i in range(resample_line_num): for j in range(resample_sample_num): position_list.append( ((i + 1) * resample_step - 1, (j + 1) * resample_step - 1)) gcps_list = [] for each in position_list: lie = each[1] hang = each[0] lon = float(lon_data[hang][lie]) lat = float(lat_data[hang][lie]) gdal_gcp = gdal.GCP(lon, lat, 0, lie, hang) gcps_list.append(gdal_gcp) sr = osr.SpatialReference() sr.SetWellKnownGeogCS('WGS84') # 添加控制点 dataset.SetGCPs(gcps_list, sr.ExportToWkt()) out_tif_path = r'E:\NPP\temp\svi01_proj.tif.' dst_ds = gdal.Warp(out_tif_path, dataset, format='GTiff', tps=True, xRes=0.0037, yRes=0.0037, dstNodata=65533, resampleAlg=gdal.GRIORA_NearestNeighbour, outputType=gdal.GDT_UInt16) """
def raster_clip_by_shp(in_path, out_path, shp_path, nodata_val=-9999): """ 依据shp边界对栅格数据进行裁切,输出TIF投影和输入TIF投影一致 :param in_path: str: 栅格文件路径 :param out_path: str: 输出栅格文件路径 :param shp_path: str: 矢量文件路径 :param nodata_val: float: 背景值 :return: """ try: shp_obj = ShapeFile(shp_path) shp_obj.readShp() shp_extend = shp_obj.getExtent() # 获取矢量经纬度范围 tif_obj = GeoTiffFile(in_path) tif_obj.readTif() xres = tif_obj.getXRes() # 获取栅格分辨率 yres = tif_obj.getYRes() out_bounds = (shp_extend["xMin"], shp_extend["yMin"], shp_extend["xMax"], shp_extend["yMax"]) # 方案1:裁切结果与shp左、上相切,强制分辨率与原始保持一致 ds = gdal.Warp(out_path, in_path, format='GTiff', outputBounds=out_bounds, dstNodata=nodata_val, cutlineDSName=shp_path, cropToCutline=False, xRes=xres, yRes=yres) # 方案2:裁切结果不会偏移,取shp内部像元,分辨率不变 # ds = gdal.Warp(out_path, in_path, format='GTiff', outputBounds=out_bounds, dstNodata=nodata_val, # cutlineDSName=shp_path, cropToCutline=True) if not ds: return False del ds return True except Exception as e: print(e) return False
def write_tif(data, band, width, height, proj, geotrans, outpath): outTifObj = GeoTiffFile(outpath) outTifObj.setDims(width, height, band) outTifObj.setProj(proj) outTifObj.setGeoTrans(geotrans) outTifObj.setData(data) outTifObj.writeTif()
def rasterSynthesis(inputFileList, outputPath, mode, valueRange, bgValue=-9999, extent=None, res=None): """ 单波段栅格文件最大/最小/均值合成功能 默认输入文件分辨率和经纬度范围一致 也可指定经纬度范围和分辨率进行重采样,参数(extent, res) :param inputFileList: list 输入文件路径列表,文件之间以","隔开 :param outputPath: str 合成输出文件路径 :param mode: str 合成方法 可选参数 ("mean", "max", "min") :param valueRange: list 合成有效值范围 e.g [-1,1] :param bgValue: float 合成结果中无效值设定 默认-9999 :param extent: 输出文件经纬度范围 默认与第一个文件保持一致 {"xMin": lonMin, "xMax": lonMax, "yMin": latMin, "yMax": latMax} :param res: float 输出文件分辨率 默认与第一个文件保持一致 :return: """ try: sampleTifObj = GeoTiffFile(inputFileList[0]) sampleTifObj.readTif() # 判断参数是否指定经纬度范围和分辨率 if extent is None: extentInfo = sampleTifObj.getGeoExtent() else: extentInfo = extent if res is None: resInfo = sampleTifObj.getXRes() else: resInfo = res # 获取输出行列号 warpDs = GdalUtil.raster_warp(inputFileList[0], "", extentInfo, resInfo, mode="MEM") if warpDs is None: return None width = warpDs.RasterXSize height = warpDs.RasterYSize trans = warpDs.GetGeoTransform() proj = warpDs.GetProjection() del warpDs # 三种合成方式max/min/mean # 1.mean if mode.upper() == "MEAN": countArray = np.zeros((height, width), dtype=np.uint16) # 计数器 sumArray = np.zeros((height, width), dtype=np.float32) # 总和 for f in inputFileList: warpDs = GdalUtil.raster_warp(f, "", extentInfo, resInfo, mode="MEM") array = warpDs.GetRasterBand(1).ReadAsArray() loc = np.logical_and(array > valueRange[0], array <= valueRange[1]) countArray[loc] = countArray[loc] + 1 sumArray[loc] = sumArray[loc] + array[loc] outArray = sumArray / countArray outArray[countArray == 0] = bgValue # 2.max elif mode.upper() == "MAX": outArray = np.ones( (height, width), dtype=np.float32) * valueRange[0] for f in inputFileList: warpDs = GdalUtil.raster_warp(f, "", extentInfo, resInfo, mode="MEM") array = warpDs.GetRasterBand(1).ReadAsArray() array = array.astype(np.float32) nanLoc = np.logical_or(array <= valueRange[0], array > valueRange[1]) array[nanLoc] = np.nan loc = array > outArray outArray[loc] = array[loc] nanLoc = np.logical_or(outArray <= valueRange[0], outArray > valueRange[1]) outArray[nanLoc] = bgValue # 3.min elif mode.upper() == "MIN": outArray = np.ones( (height, width), dtype=np.float32) * (valueRange[1] + 1) for f in inputFileList: warpDs = GdalUtil.raster_warp(f, "", extentInfo, resInfo, mode="MEM") array = warpDs.GetRasterBand(1).ReadAsArray() array = array.astype(np.float32) nanLoc = np.logical_or(array <= valueRange[0], array > valueRange[1]) array[nanLoc] = np.nan loc = array < outArray outArray[loc] = array[loc] nanLoc = np.logical_or(outArray <= valueRange[0], outArray > valueRange[1]) outArray[nanLoc] = bgValue else: print("Cannot calculate with mode :" + mode) outTifObj = GeoTiffFile(outputPath) outTifObj.setDims(width, height, 1) outTifObj.setGeoTrans(trans) outTifObj.setProj(proj) outTifObj.setData(outArray) outTifObj.writeTif() except Exception as e: return None
def get_sixs_param(warp_path, temp_dir, file_basename): sixs_exe_path = r'C:\6S\6s.exe' in_txt_path = os.path.join(os.path.dirname(sixs_exe_path), 'in.txt') angle = {'SolarZenithAngle': None, 'SolarAzimuthAngle': None, 'SatelliteZenithAngle': None, 'SatelliteAzimuthAngle': None} extent = {'xMin': 119.89, 'xMax': 120.64, 'yMin': 30.93, 'yMax': 31.55} for each in angle.keys(): clip_tif_path = os.path.join(temp_dir, os.path.basename(warp_path[each]).replace('.tif', '_clip.tif')) GdalUtil.raster_warp(warp_path[each], clip_tif_path, extent, 0.004667, nodata_val=65533) tif_obj = GeoTiffFile(clip_tif_path) tif_obj.readTif() extent = tif_obj.getGeoExtent() data_array = tif_obj.getBandData(0) data_array[data_array == 65533] = np.nan angle_mean = abs(float(np.nanmean(data_array))) angle[each] = angle_mean # 月 日 month = int(file_basename.split('_')[2][5:7]) day = int(file_basename.split('_')[2][7:9]) # 大气模式 center_lat = (extent['yMax'] + extent['yMin']) / 2 if center_lat < 23.5 and month < 9 and month > 2: atmo_model = 1 elif center_lat >= 23.5 and center_lat < 66.5 and month < 9 and month > 2: atmo_model = 2 elif center_lat >= 23.5 and center_lat < 66.5 and (month >= 9 or month <= 2): atmo_model = 3 elif center_lat >= 66.5 and month < 9 and month > 2: atmo_model = 4 elif center_lat >= 66.5 and (month >= 9 or month <= 2): atmo_model = 5 else: # 错误 atmo_model = 0 # 波长范围 wave_range = {'svi01': (0.6025, 0.6775), 'svi02': (0.8455, 0.8845), 'svi03': (1.58, 1.64), 'svi04': (3.55, 3.93)} atmo_param = {'svi01': None, 'svi02': None, 'svi03': None, 'svi04': None} for each in atmo_param.keys(): # 写入in.txt with open(in_txt_path, 'w') as f: f.write('%d\n' % 0) # 自定义几何 f.write('%.2f\n' % angle['SolarZenithAngle']) # 太阳天顶角 f.write('%.2f\n' % angle['SolarAzimuthAngle']) # 太阳方位角 f.write('%.2f\n' % angle['SatelliteZenithAngle']) # 卫星天顶角 f.write('%.2f\n' % angle['SatelliteAzimuthAngle']) # 卫星方位角 f.write('%d\n' % month) # 月 f.write('%d\n' % day) # 日 f.write('%d\n' % atmo_model) # 大气模式 f.write('%d\n' % 1) # 气溶胶类型 f.write('%.1f\n' % 15.0) # 气溶胶参数 f.write('%.3f\n' % -0.010) # 目标高度 f.write('%d\n' % -1000) # 传感器高度 f.write('%d\n' % 0) # 自定义输入波长 f.write('%.4f\n' % wave_range[each][0]) # 波长起始 f.write('%.4f\n' % wave_range[each][1]) # 波长终止 f.write('%d\n' % 0) # 无方向反射 f.write('%d\n' % 0) # 朗伯体假设 f.write('%d\n' % 4) # 湖泊水体 f.write('%.1f\n' % -0.4) # 进行大气校正 sixs_exe_dir = os.path.dirname(sixs_exe_path) sixs_exe_name = os.path.basename(sixs_exe_path) cmd_str = 'cd %s && %s<%s>log.txt' % (sixs_exe_dir, sixs_exe_name, 'in.txt') os.system(cmd_str) sixs_out_path = os.path.join(sixs_exe_dir, 'sixs.out') with open(sixs_out_path, 'r') as f1: line_str = f1.readline() while line_str: line_str = f1.readline() # print(line_str) if 'coefficients xa xb xc' in line_str: atmo_param_str = line_str.split(':')[1] xa = float(atmo_param_str.split(' ')[1]) xb = float(atmo_param_str.split(' ')[2]) xc = float(atmo_param_str.split(' ')[3]) print(xa, xb, xc) atmo_param[each] = (xa, xb, xc) return atmo_param
def cal_radiance(warp_path, atmo_param, out_tif_path): radiance_factor = {'svi01': (0.013155036, -0.41), 'svi02': (0.0063949213, -0.24), 'svi03': (0.0013309018, -0.21), 'svi04': (5.52444e-05, -0.01)} # 先获取行列号 tif_path = warp_path['svi01'] tif_obj = GeoTiffFile(tif_path) tif_obj.readTif() width = tif_obj.getWidth() height = tif_obj.getHeight() proj = tif_obj.getProj() geo_trans = tif_obj.getGeoTrans() del tif_obj out_tif_obj = GeoTiffFile(out_tif_path) out_tif_data = np.zeros((4, height, width), dtype=np.float) i = 0 for key in radiance_factor.keys(): tif_path = warp_path[key] tif_obj = GeoTiffFile(tif_path) tif_obj.readTif() tif_data = tif_obj.getBandData(0) nan_loc = tif_data >= 65530 # 辐射定标计算 tif_data = tif_data * radiance_factor[key][0] + radiance_factor[key][1] # 大气校正计算 # y=xa*(measured radiance)-xb; acr=y/(1.+xc*y) y = atmo_param[key][0] * tif_data - atmo_param[key][1] ref_data = y / (1 + atmo_param[key][2] * y) * 1000 # ref_data = ref_data.astype(np.uint16) ref_data[nan_loc] = 65533 out_tif_data[i, :, :] = ref_data i += 1 out_tif_obj.setDims(width, height, 4) out_tif_obj.setData(out_tif_data) out_tif_obj.setProj(proj) out_tif_obj.setGeoTrans(geo_trans) out_tif_obj.writeTif() print("finish")