def imperviousness_raster(): out_file_name = 'neigh_imp.tif' imp_rast = Raster('nor_imperv.tif') neighborhood = NbrRectangle(width=1500, height=1500, units="MAP") neigh_imp = FocalStatistics(imp_rast, neighborhood=neighborhood, statistics_type="SUM", ignore_nodata="DATA") neigh_imp.save(out_file_name) return out_file_name
def surface_relief(elevation_input, relief_output): """ Description: calculates 32-bit float surface relief ratio Inputs: 'elevation_input' -- an input raster digital elevation model 'relief_output' -- an output surface relief ratio raster Returned Value: Returns a raster dataset on disk Preconditions: requires an input elevation raster """ # Import packages import arcpy from arcpy.sa import Con from arcpy.sa import Float from arcpy.sa import FocalStatistics from arcpy.sa import NbrRectangle # Set overwrite option arcpy.env.overwriteOutput = True # Define a neighborhood variable neighborhood = NbrRectangle(5, 5, "CELL") # Calculate local minimum print('\t\tCalculating local minimum...') local_minimum = FocalStatistics(elevation_input, neighborhood, 'MINIMUM', 'DATA') # Calculate local maximum print('\t\tCalculating local maximum...') local_maximum = FocalStatistics(elevation_input, neighborhood, 'MAXIMUM', 'DATA') # Calculate local mean print('\t\tCalculating local mean...') local_mean = FocalStatistics(elevation_input, neighborhood, 'MEAN', 'DATA') # Calculate maximum drop print('\t\tCalculating maximum drop...') maximum_drop = Float(local_maximum - local_minimum) # Calculate standardized drop print('\t\tCalculating standardized drop...') standardized_drop = Float(local_mean - local_minimum) / maximum_drop # Calculate surface relief ratio print('\t\tCalculating surface relief ratio...') out_raster = Con(maximum_drop == 0, 0, standardized_drop) out_raster.save(relief_output)
def main(bathy=None, inner_radius=None, outer_radius=None, out_raster=None, bpi_type='broad'): """ Create a bathymetric position index (BPI) raster, which measures the average value in a 'donut' of locations, excluding cells too close to the origin point, and outside a set distance. """ arcpy.env.compression = "LZW" arcpy.env.rasterStatistics = "STATISTICS" try: # Create the broad-scale Bathymetric Position Index (BPI) raster msg = ("Generating the {bpi_type}-scale Bathymetric" "Position Index (BPI) raster...".format(bpi_type=bpi_type)) utils.msg(msg) utils.msg("Calculating neighborhood...") neighborhood = NbrAnnulus(inner_radius, outer_radius, "CELL") utils.msg("Calculating FocalStatistics for {}...".format(bathy)) out_focal_statistics = FocalStatistics(bathy, neighborhood, "MEAN") result_raster = Int(Plus(Minus(bathy, out_focal_statistics), 0.5)) out_raster_path = utils.validate_path(out_raster) arcpy.CopyRaster_management(result_raster, out_raster_path) utils.msg("Saved output as {}".format(out_raster_path)) except Exception as e: utils.msg(e, mtype='error')
def topographic_position(elevation_input, position_output): """ Description: calculates 32-bit float topographic position Inputs: 'elevation_input' -- an input raster digital elevation model 'relief_output' -- an output surface relief ratio raster Returned Value: Returns a raster dataset on disk Preconditions: requires an input elevation raster """ # Import packages import arcpy from arcpy.sa import FocalStatistics from arcpy.sa import NbrRectangle from arcpy.sa import Raster # Set overwrite option arcpy.env.overwriteOutput = True # Define a neighborhood variable neighborhood = NbrRectangle(5, 5, "CELL") # Calculate local mean print('\t\tCalculating local mean...') local_mean = FocalStatistics(elevation_input, neighborhood, 'MEAN', 'DATA') # Calculate topographic position print('\t\tCalculating topographic position...') out_raster = Raster(elevation_input) - local_mean out_raster.save(position_output)
def roughness(elevation_input, roughness_output): """ Description: calculates 32-bit float roughness Inputs: 'elevation_input' -- an input raster digital elevation model 'roughness_output' -- an output roughness raster Returned Value: Returns a raster dataset on disk Preconditions: requires an input elevation raster """ # Import packages import arcpy from arcpy.sa import FocalStatistics from arcpy.sa import NbrRectangle from arcpy.sa import Raster from arcpy.sa import Square # Set overwrite option arcpy.env.overwriteOutput = True # Define a neighborhood variable neighborhood = NbrRectangle(5, 5, "CELL") # Calculate the elevation standard deviation print('\t\tCalculating standard deviation...') standard_deviation = FocalStatistics(Raster(elevation_input), neighborhood, 'STD', 'DATA') # Calculate the square of standard deviation print('\t\tCalculating squared standard deviation...') out_raster = Square(standard_deviation) out_raster.save(roughness_output)
def main(in_raster=None, neighborhood_size=None, out_workspace=None, out_stats_raw=None): """ Compute depth statisitcs, averaging values over a defined neighborhood of cells. Can compute mean, standard deviation, and variance. """ out_stats = out_stats_raw.replace("'", '').split(";") arcpy.env.rasterStatistics = "STATISTICS" # convert our data to sets for easy comparison mean_set = set(['Mean Depth']) std_dev_set = set(['Standard Deviation', 'Variance']) # list stats to be computed utils.msg("The following stats will be computed: " + \ "{}".format(";".join(out_stats))) try: # initialize our neighborhood utils.msg("Calculating neighborhood...") neighborhood = NbrRectangle(neighborhood_size, neighborhood_size, "CELL") if mean_set.intersection(out_stats): utils.msg("Calculating mean depth...") mean_depth = FocalStatistics(in_raster, neighborhood, "MEAN", "NODATA") mean_raster = os.path.join(out_workspace, "meandepth") utils.msg("saving mean depth to {}".format(mean_raster)) mean_depth.save(mean_raster) # compute stdev in ths case if std_dev_set.intersection(out_stats): utils.msg("Calculating depth standard deviation...") std_dev_depth = FocalStatistics(in_raster, neighborhood, "STD", "NODATA") std_dev_raster = os.path.join(out_workspace, "stdevdepth") utils.msg( "saving standard deviation depth to {}".format(std_dev_raster)) std_dev_depth.save(std_dev_raster) # no direct variance focal stat, have to stdev^2 if 'Variance' in out_stats: utils.msg("Calculating depth variance...") var_depth = Power(std_dev_depth, 2) var_raster = os.path.join(out_workspace, "vardepth") utils.msg("saving depth variance to {}".format(var_raster)) var_depth.save(var_raster) except Exception as e: utils.msg(e, mtype='error')
def linear_aspect(raw_aspect, aspect_output): """ Description: calculates 32-bit float linear aspect Inputs: 'raw_aspect' -- an input raw aspect raster 'aspect_output' -- an output linear aspect raster Returned Value: Returns a raster dataset on disk Preconditions: requires an input DEM """ # Import packages import arcpy from arcpy.sa import ATan2 from arcpy.sa import Con from arcpy.sa import Cos from arcpy.sa import FocalStatistics from arcpy.sa import Mod from arcpy.sa import NbrRectangle from arcpy.sa import Raster from arcpy.sa import SetNull from arcpy.sa import Sin # Set overwrite option arcpy.env.overwriteOutput = True # Define a neighborhood variable neighborhood = NbrRectangle(3, 3, "CELL") # Calculate aspect transformations print('\t\tTransforming raw aspect to linear aspect...') setNull_aspect = SetNull( Raster(raw_aspect) < 0, (450.0 - Raster(raw_aspect)) / 57.296) sin_aspect = Sin(setNull_aspect) cos_aspect = Cos(setNull_aspect) sum_sin = FocalStatistics(sin_aspect, neighborhood, "SUM", "DATA") sum_cos = FocalStatistics(cos_aspect, neighborhood, "SUM", "DATA") mod_aspect = Mod( ((450 - (ATan2(sum_sin, sum_cos) * 57.296)) * 100), 36000 ) / 100 # The *100 and 36000(360*100) / 100 allow for two decimal points since Fmod appears to be gone out_raster = Con((sum_sin == 0) & (sum_cos == 0), -1, mod_aspect) # Save output raster file out_raster.save(aspect_output)
def calcConiferPost(coniferTreatmentArea, Conifer_Cover): arcpy.AddMessage("Calculating post-project conifer modifier") # Add field Conifer to use when converting to raster inTable = coniferTreatmentArea fieldName = "Conifer" fieldType = "SHORT" expression = 0 arcpy.AddField_management(inTable, fieldName, fieldType) arcpy.CalculateField_management(inTable, fieldName, expression, "PYTHON_9.3", "") # Convert to raster in_features = coniferTreatmentArea value_field = "Conifer" out_rasterdataset = "Proposed_Conifer_Cover" cell_assignment = "MAXIMUM_AREA" priority_field = "Conifer" cellSize = 30 coniferRaster = arcpy.PolygonToRaster_conversion(in_features, value_field, out_rasterdataset, cell_assignment, priority_field, cellSize) # Mask existing conifer cover coniferPost = Con(IsNull(coniferRaster), Conifer_Cover, coniferRaster) coniferPost.save("Post_Conifer_Cover") # Calculate neighborhood statistics in_raster = coniferPost radius = 400 neighborhood = NbrCircle(radius, "MAP") statistics_type = "MEAN" coniferCover400 = FocalStatistics(in_raster, neighborhood, statistics_type) # Reclassify to get Post_Conifer_Modifier in_raster = coniferCover400 reclass_field = "VALUE" remapTable = [[0, 1, 100], [1, 2, 28], [2, 3, 14], [3, 4, 9], [4, 5, 6], [5, 7, 3], [7, 8, 2], [8, 9, 1], [9, 100, 0]] coniferModifierPost100 = Reclassify(in_raster, reclass_field, RemapRange(remapTable)) coniferModifierPost = Float(coniferModifierPost100) / 100 return coniferModifierPost
def main(in_raster=None, neighborhood_size=None, out_workspace=None, out_stats_raw=None): out_stats = out_stats_raw.replace("'", '').split(";") arcpy.env.rasterStatistics = "STATISTICS" # convert our data to sets for easy comparison mean_set = set(['Mean Depth']) std_dev_set = set(['Standard Deviation', 'Variance']) # list stats to be computed utils.msg("The following stats will be computed: {}".format(";".join(out_stats))) try: # initialize our neighborhood utils.msg("Calculating neighborhood...") neighborhood = NbrRectangle(neighborhood_size, neighborhood_size, "CELL") if mean_set.intersection(out_stats): utils.msg("Calculating mean depth...") mean_depth = FocalStatistics(in_raster, neighborhood, "MEAN", "NODATA") mean_raster = os.path.join(out_workspace, "meandepth") utils.msg("saving mean depth to {}".format(mean_raster)) mean_depth.save(mean_raster) # compute stdev in ths case if std_dev_set.intersection(out_stats): utils.msg("Calculating depth standard deviation...") std_dev_depth = FocalStatistics(in_raster, neighborhood, "STD", "NODATA") std_dev_raster = os.path.join(out_workspace, "stdevdepth") utils.msg("saving standard deviation depth to {}".format(std_dev_raster)) std_dev_depth.save(std_dev_raster) # no direct variance focal stat, have to stdev^2 if 'Variance' in out_stats: utils.msg("Calculating depth variance...") var_depth = Power(std_dev_depth, 2) var_raster = os.path.join(out_workspace, "vardepth") utils.msg("saving depth variance to {}".format(var_raster)) var_depth.save(var_raster) except Exception as e: utils.msg(e, mtype='error')
def main(in_raster=None, neighborhood_size=None, out_raster=None): """ Compute terrain ruggedness, using the vector ruggedness measure (VRM), as described in: Sappington et al., 2007. Quantifying Landscape Ruggedness for Animal Habitat Analysis: A Case Study Using Bighorn Sheep in the Mojave Desert. Journal of Wildlife Management. 71(5): 1419 -1426. """ hood_size = int(neighborhood_size) # FIXME: expose this as an option per #18 w = utils.Workspace() if w.exists: out_workspace = w.path else: out_workspace = os.path.dirname(out_raster) utils.workspace_exists(out_workspace) # force temporary stats to be computed in our output workspace arcpy.env.scratchWorkspace = out_workspace arcpy.env.workspace = out_workspace # TODO expose as config pyramid_orig = arcpy.env.pyramid arcpy.env.pyramid = "NONE" # TODO: currently set to automatically overwrite, expose this as option arcpy.env.overwriteOutput = True arcpy.env.compression = 'LZW' try: # Create Slope and Aspect rasters utils.msg("Calculating aspect...") out_aspect = Aspect(in_raster) utils.msg("Calculating slope...") out_slope = Slope(in_raster, "DEGREE") # Convert Slope and Aspect rasters to radians utils.msg("Converting slope and aspect to radians...") slope_rad = out_slope * (math.pi / 180) aspect_rad = out_aspect * (math.pi / 180) # Calculate x, y, and z rasters utils.msg("Calculating x, y, and z rasters...") xy_raster_calc = Sin(slope_rad) z_raster_calc = Cos(slope_rad) x_raster_calc = Con(out_aspect == -1, 0, Sin(aspect_rad)) * xy_raster_calc y_raster_calc = Con(out_aspect == -1, 0, Cos(aspect_rad)) * xy_raster_calc # Calculate sums of x, y, and z rasters for selected neighborhood size utils.msg("Calculating sums of x, y, and z rasters in neighborhood...") hood = NbrRectangle(hood_size, hood_size, "CELL") x_sum_calc = FocalStatistics(x_raster_calc, hood, "SUM", "NODATA") y_sum_calc = FocalStatistics(y_raster_calc, hood, "SUM", "NODATA") z_sum_calc = FocalStatistics(z_raster_calc, hood, "SUM", "NODATA") # Calculate the resultant vector utils.msg("Calculating the resultant vector...") result_vect = (x_sum_calc**2 + y_sum_calc**2 + z_sum_calc**2)**0.5 arcpy.env.rasterStatistics = "STATISTICS" arcpy.env.pyramid = pyramid_orig # Calculate the Ruggedness raster utils.msg("Calculating the final ruggedness raster...") ruggedness = 1 - (result_vect / hood_size**2) out_raster = utils.validate_path(out_raster) utils.msg("Saving ruggedness raster to to {}.".format(out_raster)) arcpy.CopyRaster_management(ruggedness, out_raster) except Exception as e: utils.msg(e, mtype='error')
def main(in_raster=None, neighborhood_size=None, out_workspace=None, out_stats_raw=None, verbose=True, window_type='Rectangle'): """ Compute depth statisitcs, averaging values over a defined neighborhood of cells. Can compute mean, standard deviation, and variance. """ out_stats = out_stats_raw.replace("'", '').split(";") out_stats = list(set(out_stats) - set(['Terrain Ruggedness (VRM)'])) arcpy.env.rasterStatistics = "STATISTICS" arcpy.env.compression = 'LZW' # compress output rasters # neighborhood is integer n_size = int(neighborhood_size) # convert our data to sets for easy comparison mean_set = set(['Mean Depth', 'Difference to Mean']) std_dev_set = set(['Standard Deviation', 'Variance']) iqr_set = set(['Interquartile Range']) kurt_set = set(['Kurtosis']) # list stats to be computed if verbose: utils.msg("The following stats will be computed: " + "{}".format(";".join(out_stats))) # these two tools both use block processing which requires NetCDF4 if 'Interquartile Range' in out_stats or 'Kurtosis' in out_stats: if not utils.NETCDF4_EXISTS: utils.msg("The interquartile range and kurtosis tools require " "the NetCDF4 Python library is installed. NetCDF4 " "is included in ArcGIS 10.3 and later.", "error") return if 'Kurtosis' in out_stats and not utils.SCIPY_EXISTS: utils.msg("The kurtosis calculation requires the SciPy library " "is installed. SciPy is included in ArcGIS 10.4 and " "later versions.", "error") return # get output name prefix and suffix parts = output_parts(in_raster, out_workspace, n_size) utils.workspace_exists(out_workspace) # set geoprocessing environments arcpy.env.scratchWorkspace = out_workspace arcpy.env.workspace = out_workspace # validate nbr type if window_type not in ('Rectangle', 'Circle'): utils.msg("Unknown window type `{}`".format(window_type), "error") try: # initialize our neighborhood if verbose: utils.msg("Calculating neighborhood...") if window_type == 'Circle': neighborhood = arcpy.sa.NbrCircle(n_size, "CELL") else: neighborhood = arcpy.sa.NbrRectangle(n_size, n_size, "CELL") overlap = int((n_size / 2.0) - 0.5) if mean_set.intersection(out_stats): mean_requested = 'Mean Depth' in out_stats if verbose and mean_requested: utils.msg("Calculating mean depth...") mean_depth = FocalStatistics(in_raster, neighborhood, "MEAN", "NODATA") mean_raster = output_name(parts, 'mean') if verbose and mean_requested: utils.msg("saving mean depth to {}".format(mean_raster)) arcpy.CopyRaster_management(mean_depth, mean_raster) if 'Difference to Mean' in out_stats: if verbose: utils.msg("Calculating relative difference to mean...") range_depth = FocalStatistics(in_raster, neighborhood, "RANGE", "NODATA") mean_diff = -(mean_depth - in_raster) / range_depth mean_diff_raster = output_name(parts, 'mean_diff') if verbose: utils.msg("saving relative different to mean to {}".format( mean_diff_raster)) arcpy.CopyRaster_management(mean_diff, mean_diff_raster) if not mean_requested: arcpy.Delete_management(mean_raster) # compute stdev in ths case if std_dev_set.intersection(out_stats): std_dev_requested = 'Standard Deviation' in out_stats if verbose and std_dev_requested: utils.msg("Calculating depth standard deviation...") std_dev_depth = FocalStatistics(in_raster, neighborhood, "STD", "NODATA") std_dev_raster = output_name(parts, 'sdev') if verbose and std_dev_requested: utils.msg("saving standard deviation depth to \ {}".format(std_dev_raster)) arcpy.CopyRaster_management(std_dev_depth, std_dev_raster) # no direct variance focal stat, have to stdev^2 if 'Variance' in out_stats: if verbose: utils.msg("Calculating depth variance...") var_depth = Power(std_dev_depth, 2) var_raster = output_name(parts, 'var') if verbose: utils.msg("saving depth variance to {}".format(var_raster)) arcpy.CopyRaster_management(var_depth, var_raster) if not std_dev_requested: arcpy.Delete_management(std_dev_raster) # limit 3D blocksize to 10^8 elements (.4GB) on 32-bit, 10^10 on 64-bit if utils.ARCH == '32-bit': limit = 10**8 else: limit = 10**10 blocksize = int(np.sqrt((limit) / (n_size**2)) - overlap * 2) # define numpy-based calculations np_sets = ((iqr_set, "interquartile range", "iqr", iqr), (kurt_set, "kurtosis", "kurt", kurtosis)) for np_set in np_sets: (in_set, label, out_label, funct) = np_set if in_set.intersection(out_stats): if verbose: utils.msg("Calculating depth {}...".format(label)) out_raster = output_name(parts, out_label) bp = utils.BlockProcessor(in_raster) bp.computeBlockStatistics(funct, blocksize, out_raster, overlap) except Exception as e: utils.msg(e, mtype='error')