def _get_cell_arc(_r): # Check if r is a Raster Layer isRaster = checkIfRstIsLayer(_r) lyr = rst_lyr(_r) if not isRaster else _r cellsizeX = arcpy.GetRasterProperties_management( lyr, "CELLSIZEX", "" if not bnd else bnd ) cellsizeY = arcpy.GetRasterProperties_management( lyr, "CELLSIZEY", "" if not bnd else bnd ) if xy: if str(cellsizeY) != str(cellsizeX): raise ValueError(( 'Cellsize is not the same in both dimensions (x, y)' )) else: return int(str(cellsizeX)) else: return int(str(cellsizeX)), int(str(cellsizeY))
def maximum_score(raster, output, MAX=True, __template=None): """ Calculate a Maximum Score of a Raster If Max, major values will be the major values in the normalized raster; Else, major values will be the minor values in the normalizes raster. """ import os from gasp.oss import get_filename from gasp.cpu.arcg.lyr import rst_lyr from gasp.prop.rst import rst_stats from gasp.spanlst.algebra import rstcalc lyr = rst_lyr(raster) __max = rst_stats(lyr, api='arcpy')["MAX"] express = '{rst} / {_max}' if MAX else '1 - ({rst} / {_max})' rstcalc( express.format( rst=get_filename(raster), _max=str(__max) ), output, template=__template, api='arcpy' ) return output
def range_score(raster, output, MAX=True, __template=None): """ Calculate a Range Score of a Raster If Max, major values will be the major values in the normalized raster; Else, major values will be the minor values in the normalizes raster. """ import os from gasp.oss import get_filename from gasp.cpu.arcg.lyr import rst_lyr from gasp.prop.rst import rst_stats from gasp.spanlst.algebra import rstcalc lyr = rst_lyr(raster) __max = rst_stats(lyr, api='arcpy')["MAX"] __min = rst_stats(lyr, api='arcpy')["MIN"] express = '({rst} - {_min}) / ({_max} - {_min})' if MAX else \ '({_max} - {rst}) / ({_max} - {_min})' rstcalc( express.format( _min=str(__min), _max=str(__max), rst=get_filename(raster) ), output, api='arcpy' ) return output
def rst_stats(rst, bnd=None, api='gdal'): """ Get Raster Statistics The output will be a dict with the following keys: * Min - Minimum * Max - Maximum * Mean - Mean value * StdDev - Standard Deviation API's Available: * arcpy; * gdal; """ if api == 'gdal': """ Using GDAL, it will be very simple """ from osgeo import gdal r = gdal.Open(rst) bnd = r.GetRasterBand(1 if not bnd else bnd) stats = bnd.GetStatistics(True, True) dicStats = { 'MIN' : stats[0], 'MAX' : stats[1], 'MEAN' : stats[2], "STDEV" : stats[3] } elif api == 'arcpy': """ Do it with Arcpy """ import arcpy from gasp.cpu.arcg.lyr import rst_lyr lyr = rst_lyr(rst) dicStats = { 'MIN' : 'MINIMUM', 'MAX' : 'MAXIMUM', 'MEAN' : 'MEAN', "STDEV" : "STD" } for s in d: stat = round(float(str(arcpy.GetRasterProperties_management( lyr, s, "layer_1" if not bnd else bnd )).replace(',', '.')), 4) dicStats[s] = stat else: raise ValueError('Sorry, API {} is not available'.format(gisApi)) return dicStats
def euclidean_distance(shpRst, cellsize, outRst, template=None, boundary=None, snap=None): """ Euclidean distance from Spatial Analyst """ from arcpy import env from arcpy.sa import * import os arcpy.CheckOutExtension('Spatial') from gasp.prop.ff import vector_formats, raster_formats from gasp.cpu.arcg.lyr import feat_lyr, rst_lyr path_to_output = outRst if not boundary else \ os.path.join( os.path.dirname(outRst), '{n}_ext{f}'.format( n=os.path.splitext(os.path.basename(outRst))[0], f=os.path.splitext(os.path.basename(outRst))[1] ) ) inputFormat = os.path.splitext(shpRst)[1] if inputFormat in vector_formats(): inLyr = feat_lyr(shpRst) elif inputFormat in raster_formats(): inLyr = rst_lyr(shpRst) else: raise ValueError( 'Could not identify if shpRst is a feature class or a raster' ) if template: tempEnvironment0 = env.extent env.extent = template if snap: tempSnap = env.snapRaster env.snapRaster = snap outEucDistance = EucDistance(inLyr, "", cellsize, "") outEucDistance.save(path_to_output) if template: env.extent = tempEnvironment0 if snap: env.snapRaster = tempSnap if boundary: from gasp.cpu.arcg.mng.rst.proc import clip_raster clipLyr = feat_lyr(boundary) clip_raster(path_to_output, clipLyr, outRst, template=template, snap=snap)
def clip_each_feature(rst, shp, feature_id, work, out_basename): """ Clip a raster dataset for each feature in a feature class """ import arcpy import os from gasp.cpu.arcg.lyr import feat_lyr from gasp.cpu.arcg.lyr import rst_lyr from gasp.cpu.arcg.anls.exct import select_by_attr from gasp.oss.ops import create_folder # ########### # # Environment # # ########### # arcpy.env.overwriteOutput = True arcpy.env.workspace = work # ###### # # Do it! # # ###### # # Open feature class lyr_shp = feat_lyr(shp) lyr_rst = rst_lyr(rst) # Create folder for some temporary files wTmp = create_folder(os.path.join(work, 'tmp')) # Get id's field type fields = arcpy.ListFields(lyr_shp) for f in fields: if str(f.name) == str(feature_id): fld_type = f.type break expression = '{fld}=\'{_id}\'' if str(fld_type) == 'String' else \ '{fld}={_id}' del fields, f # Run the clip tool for each feature in the shp input c = arcpy.SearchCursor(lyr_shp) l = c.next() while l: fid = str(l.getValue(feature_id)) selection = select_by_attr( lyr_shp, expression.format(fld=feature_id, _id=fid), os.path.join(wTmp, 'each_{}.shp'.format(fid))) clip_rst = clip_raster(lyr_rst, selection, '{b}_{_id}.tif'.format(b=out_basename, _id=fid)) l = c.next()
def mean_rst_by_polygon(polygons, raster, work, resultShp): """ Mean of all cells intersect with the input polygon features """ import arcpy import os from gasp.cpu.arcg.lyr import feat_lyr, rst_lyr from gasp.prop.rst import rst_stats from gasp.cpu.arcg.mng.fld import add_field from gasp.mng.gen import copy_feat from gasp.cpu.arcg.anls.exct import select_by_attr from gasp.cpu.arcg.mng.rst.proc import clip_raster # ########### # # Environment # # ########### # arcpy.env.overwriteOutput = True arcpy.env.workspace = work # ###### # # Do it! # # ###### # # Copy the Input poly_copy = copy_feat(polygons, resultShp, gisApi='arcpy') # Create Layers lyrShp = feat_lyr(poly_copy) lyrRst = rst_lyr(raster) # Create field for register calculated statistics if len(os.path.basename(raster)) <= 10: fld_name = os.path.basename(raster) else: fld_name = os.path.basename(raster)[:10] add_field(lyrShp, fld_name, "DOUBLE", "20", "3") # Calculate mean c = arcpy.UpdateCursor(lyrShp) l = c.next() while l: fid = str(l.getValue("FID")) selection = select_by_attr(lyrShp, "FID={c}".format(c=fid), "poly_{c}.shp".format(c=fid)) sel_rst = clip_raster(lyrRst, selection, "clip_rst_{c}.img".format(c=fid)) mean = rst_stats(sel_rst, api='arcpy')["MEAN"] l.setValue(fld_name, mean) c.updateRow(l) l = c.next()
def floatRst_to_IntegerRst(inFolder, outFolder): """ List all folders in a folder and convert them to integer """ import arcpy import os from gasp.cpu.arcg.lyr import rst_lyr arcpy.env.workspace = inFolder rasters = arcpy.ListRasters() for rst in rasters: lyr = rst_lyr(os.path.join(inFolder, rst)) rstcalc('Int("{}")'.format(os.path.splitext(rst)[0]), os.path.join(outFolder, rst), template=os.path.join(inFolder, rst), api='arcpy')
def TIN_nodata_interpolation(inRst, boundary, prj, cellsize, outRst, workspace=None, template=None): """ Preenche os valores NoData de uma imagem raster usando um TIN """ import os from gasp.oss import get_filename from gasp.cpu.arcg.lyr import rst_lyr from gasp.cpu.arcg.lyr import feat_lyr from gasp.cpu.to.shp.arcg import rst_to_pnt from gasp.cpu.arcg._3D.mng.tin import create_tin from gasp.cpu.to.rst.arcg import tin_to_raster workspace = workspace if workspace else \ os.path.dirname(outRst) # Convert Input Raster to a Point Feature Class rstLyr = rst_lyr(inRst) pntRst = rst_to_pnt( rstLyr, os.path.join(workspace, get_filename(inRstinRst) + '.shp') ) # Create TIN pntrstLyr = feat_lyr( pntRst) lmtLyr = feat_lyr(boundary) tinInputs = ( '{bound} <None> Soft_Clip <None>;' '{rst_pnt} GRID_CODE Mass_Points <None>' ) tinOutput = os.path.join(workspace, 'tin_' + get_filename(inRst)) create_tin(tinOutput, prj, tinInputs) return tin_to_raster(tinOutput, cellsize, outRst, template=template)
def clip_several_each_feature(rst_folder, shp, feature_id, work, template=None, rst_file_format='.tif'): """ Clip a folder of rasters by each feature in a feature class The rasters clipped for a feature will be in an individual folder """ import arcpy import os from gasp.cpu.arcg.lyr import feat_lyr from gasp.cpu.arcg.lyr import rst_lyr from gasp.cpu.arcg.anls.exct import select_by_attr from gasp.cpu.arcg.mng.fld import type_fields from gasp.oss.ops import create_folder from gasp.oss import list_files # ########### # # Environment # # ########### # arcpy.env.overwriteOutput = True arcpy.env.workspace = work # ###### # # Do it! # # ###### # # Open feature class lyr_shp = feat_lyr(shp) # Create folder for some temporary files wTmp = create_folder(os.path.join(work, 'tmp')) # Split feature class in parts c = arcpy.SearchCursor(lyr_shp) l = c.next() features = {} # Get id's field type fld_type = type_fields(lyr_shp, field=feature_id) expression = '{fld}=\'{_id}\'' if str(fld_type) == 'String' else \ '{fld}={_id}' del fields, f while l: fid = str(l.getValue(feature_id)) selection = select_by_attr( lyr_shp, expression.format(fld=feature_id, _id=fid), os.path.join(wTmp, 'each_{}.shp'.format(fid))) f_lyr = feat_lyr(selection) features[fid] = f_lyr l = c.next() rasters = list_files(rst_folder, file_format='.tif') for raster in rasters: r_lyr = rst_lyr(raster) for feat in features: clip_rst = clip_raster( r_lyr, features[feat], os.path.join(work, os.path.splitext(os.path.basename(feat))[0], os.path.basename(raster)), template)
def generate_waterlines(mdt, waterbodies, accumulation_value=500, workspace=None): """ Generate Water Bodies lines """ import os from gasp.oss import get_fileformat from gasp.cpu.arcg.lyr import rst_lyr from gasp.prop.ff import vector_formats, raster_formats from gasp.spanlst.algebra import rstcalc from gasp.cpu.arcg.spanlst.hydro import fill from gasp.cpu.arcg.spanlst.hydro import flow_accumulation from gasp.cpu.arcg.spanlst.hydro import flow_direction from gasp.cpu.arcg.spanlst.hydro import stream_to_feature workspace = workspace if workspace else \ os.path.dirname(waterbodies) raster_format = os.path.splitext(os.path.basename(waterbodies))[1] arcpy.env.workspace = workspace arcpy.env.overwriteOutput = True fill_rst = fill(mdt, 'flow_raster{}'.format(raster_format), template=mdt) dire_rst = flow_direction(fill_rst, 'direction_raster{}'.format(raster_format), template=mdt) flow_acc = flow_accumulation(dire_rst, 'flow_raster{}'.format(raster_format), template=mdt) # Split water bodies from the other accumulation data lyr_flow = rst_lyr(flow_acc) outFormat = os.path.splitext(os.path.basename(waterbodies))[1] rstFormat = raster_formats() vecFormat = vector_formats() waterRst = waterbodies if outFormat in rstFormat else \ os.path.join( workspace, os.path.splitext(os.path.basename(waterbodies))[0] + raster_format ) if outFormat in vecFormat else None if not waterRst: raise ValueError('Your output is not a raster and is not a vector') waterRst = rstcalc('{r} > {a}'.format(r=os.path.splitext( os.path.basename(flow_acc))[0], a=str(accumulation_value)), waterRst, template=mdt, api='arcpy') if outFormat in vecFormat: stream_to_feature(waterRst, dire_rst, waterbodies) return waterbodies else: return waterRst