def storeRasterInArray(rasters): """Store list of raster or multi-band raster in a ndarray Parameters ---------- rasters : list list of rasters to analyse Return ---------- ndarray """ # get raster size with first raster file data = fut.readRaster(rasters[0], False) # get rasters or bands number if len(rasters) == 1: nbbands = fut.getRasterNbands(rasters[0]) elif len(rasters) > 1: nbbands = len(rasters) # Set a empty ndarrays with same dimension as input rasters outdata = np.zeros([data[1], data[0], nbbands]) # Populate output ndarrays if len(rasters) == 1: for nbband in range(nbbands): outdata[:, :, nbband] = fut.readRaster(rasters[0], True, nbband + 1)[0] elif len(rasters) > 1: for idx, raster in enumerate(rasters): outdata[:, :, idx] = fut.readRaster(raster, True)[0] else: raise Exception("No input raster provided to store in Numpy array") return outdata
def zonalstats(path, rasters, params, output, paramstats, classes="", bufferDist=None, nodata=0, gdalpath="", systemcall=True, gdalcachemax="9000"): """Compute zonal statistitics (descriptive and categorical) on multi-band raster or multi-rasters based on Point (buffered or not) or Polygon zonal vector Parameters ---------- path : string working directory rasters : list list of rasters to analyse params : list list of fid list and vector file output : vector file (sqlite, shapefile and geojson) vector file to store statistitics paramstats : list list of statistics to compute (e.g. {1:'stats', 2:'rate'}) - paramstats = {1:"rate", 2:"statsmaj", 3:"statsmaj", 4:"stats", 2:stats_cl} - stats : mean_b, std_b, max_b, min_b - statsmaj : meanmaj, stdmaj, maxmaj, minmaj of majority class - rate : rate of each pixel value (classe names) - stats_cl : mean_cl, std_cl, max_cl, min_cl of one class - val : value of corresponding pixel (only for Point geometry and without other stats) classes : nomenclature file nomenclature bufferDist : int in case of point zonal vector : buffer size gdalpath : string path of gdal binaries (for system execution) systemcall : boolean if True, wrapped raster are stored in working dir gdalcachemax : string gdal cache for wrapping operation (in Mb) """ if os.path.exists(output): return # Get bands or raster number if len(rasters) != 1: nbbands = len(rasters) else: nbbands = fut.getRasterNbands(rasters[0]) # Prepare and check validity of statistics methods and input raster paramstats = checkmethodstats(rasters, paramstats, nbbands) # Get vector file and FID list vector, idvals = params # if no vector subsetting (all features) if not idvals: idvals = getFidList(vector) # vector open and iterate features and/or buffer geom vectorname = os.path.splitext(os.path.basename(vector))[0] vectorgeomtype = vf.getGeomType(vector) vectorbuff = None # Prepare schema of output geopandas dataframe (geometry type and columns formatting) schema = setPandasSchema(paramstats, vectorgeomtype, bufferDist) # Buffer Point vector file if bufferDist and vectorgeomtype in (1, 4, 1001, 1004): vectorbuff = os.path.join(path, vectorname + "buff.shp") _ = bfo.bufferPoly(vector, vectorbuff, bufferDist=bufferDist) # Store input vector in output geopandas dataframe vectgpad = gpad.read_file(vector) # Prepare statistics columns of output geopandas dataframe stats = definePandasDf(vectgpad, idvals, paramstats, classes) # Iterate FID list dataset = vf.openToRead(vector) lyr = dataset.GetLayer() for idval in idvals: if vectorgeomtype in (1, 4, 1001, 1004): if 'val' in list(paramstats.values()): lyr.SetAttributeFilter("FID=" + str(idval)) for feat in lyr: geom = feat.GetGeometryRef() if geom: xpt, ypt, _ = geom.GetPoint() # Switch to buffered vector (Point and bufferDist) if bufferDist: if vectorbuff: vector = vectorbuff # creation of wrapped rasters success, bands = extractRasterArray(rasters, paramstats, vector, vectorgeomtype, idval, gdalpath, gdalcachemax, systemcall, path) if success: if 'val' in list(paramstats.values()): stats = extractPixelValue(rasters, bands, paramstats, xpt, ypt, stats, idval) else: stats = computeStats(bands, paramstats, stats, idval, nodata) else: print( "gdalwarp problem for feature %s (geometry error, too small area, etc.)" % (idval)) # Prepare columns name and format of output dataframe if "rate" in list(paramstats.values()) and classes != "": stats, schema = formatDataFrame(stats, schema, True, classes) else: stats, schema = formatDataFrame(stats, schema) # exportation dataframeExport(stats, output, schema)