def get_percentage_value(rst, value, includeNodata=None): """ Return the % of cells with a certain value """ import numpy from osgeo import gdal from gasp.pyt.num import count_where from gasp.gt.fmrst import rst_to_array from gasp.gt.prop.rst import get_nodata array = rst_to_array(rst) lnh, col = array.shape nrcell = lnh * col if not includeNodata: nd = get_nodata(rst, gisApi='gdal') nd_cells = count_where(array, array == nd) nrcell = nrcell - nd_cells valCount = count_where(array, array == value) perc = (valCount / float(nrcell)) * 100 return perc
def bands_to_rst(inRst, outFolder): """ Export all bands of a raster to a new dataset TODO: this could be done using gdal_translate """ import numpy import os from osgeo import gdal from gasp.gt.torst import obj_to_rst from gasp.gt.prop.rst import get_nodata rst = gdal.Open(inRst) if rst.RasterCount == 1: return nodata = get_nodata(inRst, gisApi='gdal') for band in range(rst.RasterCount): band += 1 src_band = rst.GetRasterBand(band) if src_band is None: continue else: # Convert to array array = numpy.array(src_band.ReadAsArray()) obj_to_rst(array, os.path.join( outFolder, '{r}_{b}.tif'.format(r=os.path.basename( os.path.splitext(inRst)[0]), b=str(band))), inRst, noData=nodata)
def count_cells(raster, countNodata=None): """ Return number of cells in a Raster Dataset """ from gasp.gt.fmrst import rst_to_array from gasp.pyt.num import count_where a = rst_to_array(raster) lnh, col = a.shape nrcell = lnh * col if countNodata: return nrcell else: NoDataValue = get_nodata(raster) NrNodata = count_where(a, a == NoDataValue) return nrcell - NrNodata
def percentage_nodata(rst): """ Return the % of cells with nodata value """ import numpy from gasp.pyt.num import count_where from gasp.gt.fmrst import rst_to_array from gasp.gt.prop.rst import get_nodata array = rst_to_array(rst) lnh, col = array.shape nrcell = lnh * col nd = get_nodata(rst, gisApi='gdal') nd_cells = count_where(array, array == nd) perc = (nd_cells / float(nrcell)) * 100 return perc
def comp_bnds(rsts, outRst): """ Composite Bands """ from osgeo import gdal, gdal_array from gasp.gt.fmrst import rst_to_array from gasp.gt.prop.ff import drv_name from gasp.gt.prop.rst import get_nodata from gasp.gt.prop.prj import get_rst_epsg, epsg_to_wkt # Get Arrays _as = [rst_to_array(r) for r in rsts] # Get nodata values nds = [get_nodata(r) for r in rsts] # Assume that first raster is the template img_temp = gdal.Open(rsts[0]) geo_tran = img_temp.GetGeoTransform() band = img_temp.GetRasterBand(1) dataType = gdal_array.NumericTypeCodeToGDALTypeCode(_as[0].dtype) rows, cols = _as[0].shape epsg = get_rst_epsg(rsts[0]) # Create Output drv = gdal.GetDriverByName(drv_name(outRst)) out = drv.Create(outRst, cols, rows, len(_as), dataType) out.SetGeoTransform(geo_tran) out.SetProjection(epsg_to_wkt(epsg)) # Write all bands for i in range(len(_as)): outBand = out.GetRasterBand(i + 1) outBand.SetNoDataValue(nds[i]) outBand.WriteArray(_as[i]) outBand.FlushCache() return outRst
def rst_rotation(inFolder, template, outFolder, img_format='.tif'): """ Invert raster data """ import os from osgeo import gdal from gasp.pyt.oss import lst_ff from gasp.gt.fmrst import rst_to_array from gasp.gt.prop.rst import get_nodata from gasp.gt.torst import obj_to_rst rasters = lst_ff(inFolder, file_format=img_format) for rst in rasters: a = rst_to_array(rst) nd = get_nodata(rst) obj_to_rst(a[::-1], os.path.join(outFolder, os.path.basename(rst)), template, noData=nd)
def update_globe_land_cover(original_globe_raster, osm_urban_atlas_raster, osm_globe_raster, epsg, updated_globe_raster, detailed_globe_raster): """ Update the original Glob Land 30 with the result of the conversion of OSM DATA to the Globe Land Cover nomenclature; Also updates he previous updated Glob Land 30 with the result of the conversion of osm data to the Urban Atlas Nomenclature """ import os import numpy as np from gasp.gt.fmrst import rst_to_array from gasp.gt.prop.rst import get_cellsize, get_nodata from gasp.gt.torst import obj_to_rst # ############################# # # Convert images to numpy array # # ############################# # np_globe_original = rst_to_array(original_globe_raster) np_globe_osm = rst_to_array(osm_globe_raster) np_ua_osm = rst_to_array(osm_urban_atlas_raster) # ################################## # # Check the dimension of both images # # ################################## # if np_globe_original.shape != np_globe_osm.shape: return ( 'The Globe Land 30 raster (original) do not have the same number' ' of columns/lines comparing with the Globe Land 30 derived ' 'from OSM data') elif np_globe_original.shape != np_ua_osm.shape: return ( 'The Globe Land 30 raster (original) do not have the same ' 'number of columns/lines comparing with the Urban Atlas raster ' 'derived from OSM data') elif np_globe_osm.shape != np_ua_osm.shape: return ( 'The Globe Land 30 derived from OSM data do not have the same ' 'number of columns/lines comparing with the Urban Atlas raster ' 'derived from OSM data') # ############## # # Check Cellsize # # ############## # cell_of_rsts = get_cellsize( [original_globe_raster, osm_globe_raster, osm_urban_atlas_raster], xy=True, gisApi='gdal') cell_globe_original = cell_of_rsts[original_globe_raster] cell_globe_osm = cell_of_rsts[osm_globe_raster] cell_ua_osm = cell_of_rsts[osm_urban_atlas_raster] if cell_globe_original != cell_globe_osm: return ( 'The cellsize of the Globe Land 30 raster (original) is not the ' 'same comparing with the Globe Land 30 derived from OSM data') elif cell_globe_original != cell_ua_osm: return ( 'The cellsize of the Globe Land 30 raster (original) is not the ' 'same comparing with the Urban Atlas raster derived from OSM data') elif cell_ua_osm != cell_globe_osm: return ( 'The cellsize of the Globe Land 30 derived from OSM data is not ' 'the same comparing with the Urban Atlas raster derived from ' 'OSM data') # ############################# # # Get the Value of Nodata Cells # # ############################# # nodata_glob_original = get_nodata(original_globe_raster, gisApi='gdal') nodata_glob_osm = get_nodata(osm_globe_raster, gisApi='gdal') nodata_ua_osm = get_nodata(osm_urban_atlas_raster, gisApi='gdal') # ######################################## # # Create a new map - Globe Land 30 Updated # # ######################################## # """ Create a new array with zeros... 1) The zeros will be replaced by the values in the Globe Land derived from OSM. 2) The zeros will be replaced by the values in the Original Globe Land at the cells with NULL data in the Globe Land derived from OSM. The meta array will identify values origins in the updated raster: 1 - Orinal Raster 2 - OSM Derived Raster """ update_array = np.zeros( (np_globe_original.shape[0], np_globe_original.shape[1])) update_meta_array = np.zeros( (np_globe_original.shape[0], np_globe_original.shape[1])) # 1) np.copyto(update_array, np_globe_osm, 'no', np_globe_osm != nodata_glob_osm) # 1) meta np.place(update_meta_array, update_array != 0, 2) # 2) meta np.place(update_meta_array, update_array == 0, 1) # 2) np.copyto(update_array, np_globe_original, 'no', update_array == 0) # 2) meta np.place(update_meta_array, update_array == nodata_glob_original, int(nodata_glob_original)) # noData to int np.place(update_array, update_array == nodata_glob_original, int(nodata_glob_original)) updated_meta = os.path.join( os.path.dirname(updated_globe_raster), '{n}_meta{e}'.format( n=os.path.splitext(os.path.basename(updated_globe_raster))[0], e=os.path.splitext(os.path.basename(updated_globe_raster))[1])) # Create Updated Globe Cover 30 obj_to_rst(update_array, updated_globe_raster, original_globe_raster, noData=int(nodata_glob_original)) # Create Updated Globe Cover 30 meta obj_to_rst(update_meta_array, updated_meta, original_globe_raster, noData=int(nodata_glob_original)) # ################################################# # # Create a new map - Globe Land 30 Detailed with UA # # ################################################# # np_update = rst_to_array(updated_globe_raster) detailed_array = np.zeros((np_update.shape[0], np_update.shape[1])) detailed_meta_array = np.zeros((np_update.shape[0], np_update.shape[1])) """ Replace 80 Globe Land for 11, 12, 13, 14 of Urban Atlas The meta array will identify values origins in the detailed raster: 1 - Updated Raster 2 - UA Derived Raster from OSM """ # Globe - Mantain some classes np.place(detailed_array, np_update == 30, 8) np.place(detailed_array, np_update == 30, 1) np.place(detailed_array, np_update == 40, 9) np.place(detailed_array, np_update == 40, 1) np.place(detailed_array, np_update == 50, 10) np.place(detailed_array, np_update == 50, 1) np.place(detailed_array, np_update == 10, 5) np.place(detailed_array, np_update == 10, 1) # Water bodies np.place(detailed_array, np_ua_osm == 50 or np_update == 60, 7) np.place(detailed_meta_array, np_ua_osm == 50 or np_update == 60, 1) # Urban - Where Urban Atlas IS NOT NULL np.place(detailed_array, np_ua_osm == 11, 1) np.place(detailed_meta_array, np_ua_osm == 11, 2) np.place(detailed_array, np_ua_osm == 12, 2) np.place(detailed_meta_array, np_ua_osm == 12, 2) np.place(detailed_array, np_ua_osm == 13, 3) np.place(detailed_meta_array, np_ua_osm == 13, 2) np.place(detailed_array, np_ua_osm == 14, 4) np.place(detailed_meta_array, np_ua_osm == 14, 2) # Urban Atlas - Class 30 to 6 np.place(detailed_array, np_ua_osm == 30, 6) np.place(detailed_meta_array, np_ua_osm == 30, 2) # Create Detailed Globe Cover 30 obj_to_rst(detailed_array, detailed_globe_raster, original_globe_raster, noData=0) # Create Detailed Globe Cover 30 meta detailed_meta = os.path.join( os.path.dirname(detailed_globe_raster), '{n}_meta{e}'.format( n=os.path.splitext(os.path.basename(detailed_meta))[0], e=os.path.splitext(os.path.basename(detailed_meta))[1])) obj_to_rst(detailed_meta_array, detailed_meta, original_globe_raster, noData=0)
def gdal_slope(dem, srs, slope, unit='DEGREES'): """ Create Slope Raster TODO: Test and see if is running correctly """ import numpy import math from osgeo import gdal from scipy.ndimage import convolve from gasp.gt.fmrst import rst_to_array from gasp.gt.torst import obj_to_rst from gasp.gt.prop.rst import get_cellsize, get_nodata # ################ # # Global Variables # # ################ # cellsize = get_cellsize(dem, gisApi='gdal') # Get Nodata Value NoData = get_nodata(dem) # #################### # # Produce Slope Raster # # #################### # # Get Elevation array arr_dem = rst_to_array(dem) # We have to get a array with the number of nearst cells with values with_data = numpy.zeros((arr_dem.shape[0], arr_dem.shape[1])) numpy.place(with_data, arr_dem != NoData, 1.0) mask = numpy.array([[1, 1, 1], [1, 0, 1], [1, 1, 1]]) arr_neigh = convolve(with_data, mask, mode='constant') numpy.place(arr_dem, arr_dem == NoData, 0.0) # The rate of change in the x direction for the center cell e is: kernel_dz_dx_left = numpy.array([[0, 0, 1], [0, 0, 2], [0, 0, 1]]) kernel_dz_dx_right = numpy.array([[1, 0, 0], [2, 0, 0], [1, 0, 0]]) dz_dx = (convolve(arr_dem, kernel_dz_dx_left, mode='constant') - convolve( arr_dem, kernel_dz_dx_right, mode='constant')) / (arr_neigh * cellsize) # The rate of change in the y direction for cell e is: kernel_dz_dy_left = numpy.array([[0, 0, 0], [0, 0, 0], [1, 2, 1]]) kernel_dz_dy_right = numpy.array([[1, 2, 1], [0, 0, 0], [0, 0, 0]]) dz_dy = (convolve(arr_dem, kernel_dz_dy_left, mode='constant') - convolve( arr_dem, kernel_dz_dy_right, mode='constant')) / (arr_neigh * cellsize) # Taking the rate of change in the x and y direction, the slope for the center cell e is calculated using rise_run = ((dz_dx)**2 + (dz_dy)**2)**0.5 if unit == 'DEGREES': arr_slope = numpy.arctan(rise_run) * 57.29578 elif unit == 'PERCENT_RISE': arr_slope = numpy.tan(numpy.arctan(rise_run)) * 100.0 # Estimate the slope for the cells with less than 8 neigh aux_dem = rst_to_array(dem) index_vizinhos = numpy.where(arr_neigh < 8) for idx in range(len(index_vizinhos[0])): # Get Value of the cell lnh = index_vizinhos[0][idx] col = index_vizinhos[1][idx] e = aux_dem[lnh][col] a = aux_dem[lnh - 1][col - 1] if a == NoData: a = e if lnh == 0 or col == 0: a = e b = aux_dem[lnh - 1][col] if b == NoData: b = e if lnh == 0: b = e try: c = aux_dem[lnh - 1][col + 1] if c == NoData: c = e if lnh == 0: c = e except: c = e d = aux_dem[lnh][col - 1] if d == NoData: d = e if col == 0: d = e try: f = aux_dem[lnh][col + 1] if f == NoData: f = e except: f = e try: g = aux_dem[lnh + 1][col - 1] if g == NoData: g = e if col == 0: g = e except: g = e try: h = aux_dem[lnh + 1][col] if h == NoData: h = e except: h = e try: i = aux_dem[lnh + 1][col + 1] if i == NoData: i = e except: i = e dz_dx = ((c + 2 * f + i) - (a + 2 * d + g)) / (8 * cellsize) dz_dy = ((g + 2 * h + i) - (a + 2 * b + c)) / (8 * cellsize) rise_sun = ((dz_dx)**2 + (dz_dy)**2)**0.5 if unit == 'DEGREES': arr_slope[lnh][col] = math.atan(rise_sun) * 57.29578 elif unit == 'PERCENT_RISE': arr_slope[lnh][col] = math.tan(math.atan(rise_sun)) * 100.0 # Del value originally nodata numpy.place(arr_slope, aux_dem == NoData, numpy.nan) #arr_slope[lnh][col] = slope_degres obj_to_rst(arr_slope, slope, dem)