def calcSubtypeDisturbance(AnthroFeatures, subtype, AnthroDisturbanceType): """calculate disturbance associated with each subtype""" distance = distanceDict[subtype] weight = weightDict[subtype] AnthroFeatures = Raster(AnthroFeatures) if distance > 0: arcpy.AddMessage(" Calculating direct and indirect effects of " + str(subtype)) outEucDist = EucDistance(AnthroFeatures, distance, cellSize) tmp1 = 100 - (1/(1 + Exp(((outEucDist / (distance/2))-1)*5))) * weight # sigmoidal # tmp1 = (100 - (weight * Power((1 - outEucDist/distance), 2))) # exponential # tmp1 = 100 - (weight - (outEucDist / distance) * weight) # linear tmp2 = Con(IsNull(tmp1), 100, tmp1) subtypeRaster = tmp2 subtypeRaster.save(AnthroDisturbanceType + "_" + subtype + "_Subtype_Disturbance") elif weight > 0: arcpy.AddMessage(" Calculating direct effects of " + str(subtype)) tmp3 = Con(IsNull(AnthroFeatures), 0, AnthroFeatures) subtypeRaster = 100 - (tmp3 * weight) subtypeRaster.save(AnthroDisturbanceType + "_" + subtype + "_Subtype_Disturbance") else: subtypeRaster = None return subtypeRaster
def do_score(fire, year, day, p, shp): """! Calculate score @param fire Fire to calculate score for @param year Year fire is from @param day Day score is for @param p Probability raster to compare to @param shp Shapefile for actual perimeter @return None """ orig_raster = os.path.join(run_output, fire + ".tif") orig_raster = Raster(orig_raster) if os.path.exists(orig_raster) else None prob_raster = Raster(p) raster = os.path.join(run_output, os.path.splitext(os.path.basename(shp))[0] + '.tif') perim, raster = rasterize_perim(run_output, shp, year, fire, raster) if perim: target = Raster(raster) # remove the original raster used to start the simulation r = Con(IsNull(orig_raster), prob_raster, 0.0) if orig_raster is not None else prob_raster r = SetNull(r == 0.0, r) m = Con(IsNull(orig_raster), target, 0.0) if orig_raster is not None else target m = SetNull(m == 0.0, m) hits = Con(IsNull(r), 0.0, r) * Con(IsNull(m), 0.0, 1.0) misses = Con(IsNull(r), 1.0, 0.0) * Con(IsNull(m), 0.0, 1.0) false_positives = Con(IsNull(r), 0.0, r) * Con(IsNull(m), 1.0, 0.0) tp = arcpy.RasterToNumPyArray(hits, nodata_to_value=0).sum() fn = arcpy.RasterToNumPyArray(misses, nodata_to_value=0).sum() fp = arcpy.RasterToNumPyArray(false_positives, nodata_to_value=0).sum() total_score = tp / (tp + fn + fp) #~ logging.info("Scores are {} + {} + {} = {}".format(tp, fn, fp, total_score)) scores.append([fire, year, day, p, shp, tp, fn, fp, total_score])
def CalcZonalStats(in_zone_data, zone_field, in_value_raster, out_table): """ Resamples inValueRaster to 5m pixel size and calculates the average value within each map unit. Higher resolution required for map units <5 acres. :param in_zone_data: the Map Units Dissolve feature class :param zone_field: the field to use as zone field, must be integer and cannot be OBJECTID :param in_value_raster: raster dataset or basename as a string :param out_table: a name to save the ouput table as a string :return: None """ # Convert null values to 0 so that they are not ignored when summarizing in_value_raster = Con(IsNull(in_value_raster),0,in_value_raster) # Resample to avoid small map units returning null values resample = True if resample: # Resample raster tmp_raster = "sub_raster" arcpy.Resample_management(in_value_raster, tmp_raster, "5", "NEAREST") else: tmp_raster = in_value_raster # Calculate zonal statistics arcpy.gp.ZonalStatisticsAsTable_sa(in_zone_data, zone_field, tmp_raster, out_table, "DATA", "MEAN") if resample: arcpy.Delete_management(tmp_raster)
def combineProposedWithCurrentDebit(anthroPath, uniqueProposedSubtypes): for subtype in uniqueProposedSubtypes: # Merge proposed and current feature rasters currentAnthroFeature = Raster(os.path.join(anthroPath, subtype)) proposedAnthroFeature = Raster("Proposed_" + subtype) postAnthroFeature = Con(IsNull(proposedAnthroFeature), currentAnthroFeature, proposedAnthroFeature) postAnthroFeature.save(os.path.join("Post_" + subtype))
def create_mask(path_to_temp): arcpy.CheckOutExtension('Spatial') inputrasters = arcpy.GetParameterAsText(1).split(";") rasterlist = [] for elements in inputrasters: rasterobject = Raster(elements) rasterlist.append(rasterobject) rasterlistSum = sum(rasterlist) outcon = Con(IsNull(rasterlistSum) == 0,1) # result raster has 1 when value meets value and NoData when value meets NoData outcon.save(join(path_to_temp,"mask")) # filename is 'mask' #arcpy.CheckInExtension('Spatial') path_to_mask = join(path_to_temp,"mask") if arcpy.Exists(path_to_mask): arcpy.AddMessage("Creating mask.") return path_to_mask
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 function(DEM, streamNetwork, smoothDropBuffer, smoothDrop, streamDrop, outputReconDEM): try: # Set environment variables arcpy.env.extent = DEM arcpy.env.mask = DEM arcpy.env.cellSize = DEM # Set temporary variables prefix = "recon_" streamRaster = prefix + "streamRaster" # Determine DEM cell size and OID column name size = arcpy.GetRasterProperties_management(DEM, "CELLSIZEX") OIDField = arcpy.Describe(streamNetwork).OIDFieldName # Convert stream network to raster arcpy.PolylineToRaster_conversion(streamNetwork, OIDField, streamRaster, "", "", size) # Work out distance of cells from stream distanceFromStream = EucDistance(streamRaster, "", size) # Elements within a buffer distance of the stream are smoothly dropped intSmoothDrop = Con(distanceFromStream > float(smoothDropBuffer), 0, (float(smoothDrop) / float(smoothDropBuffer)) * (float(smoothDropBuffer) - distanceFromStream)) del distanceFromStream # Burn this smooth drop into DEM. Cells in stream are sharply dropped by the value of "streamDrop" binaryStream = Con(IsNull(Raster(streamRaster)), 0, 1) reconDEMTemp = Raster(DEM) - intSmoothDrop - (float(streamDrop) * binaryStream) del intSmoothDrop del binaryStream reconDEMTemp.save(outputReconDEM) del reconDEMTemp log.info("Reconditioned DEM generated") except Exception: log.error("DEM reconditioning function failed") raise
def merge_spectral_tiles(**kwargs): """ Description: extracts spectral tiles to an area and mosaics extracted tiles with first data priority Inputs: 'cell_size' -- a cell size for the output spectral raster 'output_projection' -- the machine number for the output projection 'work_geodatabase' -- a geodatabase to store temporary results 'input_array' -- an array containing the grid raster (must be first), the study area raster (must be second), and the list of spectral tiles 'output_array' -- an array containing the output spectral grid raster Returned Value: Returns a raster dataset on disk containing the merged spectral grid raster Preconditions: requires processed source spectral tiles and predefined grid """ # Import packages import arcpy from arcpy.sa import ExtractByMask from arcpy.sa import IsNull from arcpy.sa import Nibble from arcpy.sa import Raster from arcpy.sa import SetNull import datetime import os import time # Parse key word argument inputs cell_size = kwargs['cell_size'] output_projection = kwargs['output_projection'] work_geodatabase = kwargs['work_geodatabase'] tile_inputs = kwargs['input_array'] grid_raster = tile_inputs.pop(0) study_area = tile_inputs.pop(0) spectral_grid = kwargs['output_array'][0] # Set overwrite option arcpy.env.overwriteOutput = True # Use two thirds of cores on processes that can be split. arcpy.env.parallelProcessingFactor = "75%" # Set snap raster and extent arcpy.env.snapRaster = study_area arcpy.env.extent = Raster(grid_raster).extent # Define the output coordinate system output_system = arcpy.SpatialReference(output_projection) # Define intermediate rasters mosaic_raster = os.path.splitext(spectral_grid)[0] + '_mosaic.tif' nibble_raster = os.path.splitext(spectral_grid)[0] + '_nibble.tif' spectral_area = os.path.splitext(spectral_grid)[0] + '_area.tif' # Define folder structure grid_title = os.path.splitext(os.path.split(grid_raster)[1])[0] mosaic_location, mosaic_name = os.path.split(mosaic_raster) # Create source folder within mosaic location if it does not already exist source_folder = os.path.join(mosaic_location, 'sources') if os.path.exists(source_folder) == 0: os.mkdir(source_folder) # Create an empty list to store existing extracted source rasters for the grid input_length = len(tile_inputs) input_rasters = [] # Identify raster extent of grid print(f'\tExtracting {input_length} spectral tiles...') grid_extent = Raster(grid_raster).extent grid_array = arcpy.Array() grid_array.add(arcpy.Point(grid_extent.XMin, grid_extent.YMin)) grid_array.add(arcpy.Point(grid_extent.XMin, grid_extent.YMax)) grid_array.add(arcpy.Point(grid_extent.XMax, grid_extent.YMax)) grid_array.add(arcpy.Point(grid_extent.XMax, grid_extent.YMin)) grid_array.add(arcpy.Point(grid_extent.XMin, grid_extent.YMin)) grid_polygon = arcpy.Polygon(grid_array) # Save grid polygon grid_feature = os.path.join(work_geodatabase, 'grid_polygon') arcpy.management.CopyFeatures(grid_polygon, grid_feature) arcpy.management.DefineProjection(grid_feature, output_system) # Iterate through all input tiles and extract to grid if they overlap count = 1 for raster in tile_inputs: output_raster = os.path.join(source_folder, os.path.split(raster)[1]) if os.path.exists(output_raster) == 0: # Identify raster extent of tile tile_extent = Raster(raster).extent tile_array = arcpy.Array() tile_array.add(arcpy.Point(tile_extent.XMin, tile_extent.YMin)) tile_array.add(arcpy.Point(tile_extent.XMin, tile_extent.YMax)) tile_array.add(arcpy.Point(tile_extent.XMax, tile_extent.YMax)) tile_array.add(arcpy.Point(tile_extent.XMax, tile_extent.YMin)) tile_array.add(arcpy.Point(tile_extent.XMin, tile_extent.YMin)) tile_polygon = arcpy.Polygon(tile_array) # Save tile polygon tile_feature = os.path.join(work_geodatabase, 'tile_polygon') arcpy.CopyFeatures_management(tile_polygon, tile_feature) arcpy.DefineProjection_management(tile_feature, output_system) # Select tile extent with grid extent selection = int( arcpy.GetCount_management( arcpy.management.SelectLayerByLocation( tile_feature, 'INTERSECT', grid_feature, '', 'NEW_SELECTION', 'NOT_INVERT')).getOutput(0)) # If tile overlaps grid then perform extraction if selection == 1: # Extract raster to mask print( f'\t\tExtracting spectral tile {count} of {input_length}...' ) iteration_start = time.time() extract_raster = ExtractByMask(raster, grid_raster) # Copy extracted raster to output print(f'\t\tSaving spectral tile {count} of {input_length}...') arcpy.management.CopyRaster(extract_raster, output_raster, '', '0', '-32768', 'NONE', 'NONE', '16_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE', 'CURRENT_SLICE', 'NO_TRANSPOSE') # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Report success print( f'\t\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t\t----------') # If tile does not overlap grid then report message else: print( f'\t\tSpectral tile {count} of {input_length} does not overlap grid...' ) print('\t\t----------') # Remove tile feature class if arcpy.Exists(tile_feature) == 1: arcpy.management.Delete(tile_feature) # If extracted tile already exists then report message else: print( f'\t\tExtracted spectral tile {count} of {input_length} already exists...' ) print('\t\t----------') # If the output raster exists then append it to the raster list if os.path.exists(output_raster) == 1: input_rasters.append(output_raster) count += 1 # Remove grid feature if arcpy.Exists(grid_feature) == 1: arcpy.management.Delete(grid_feature) print(f'\tFinished extracting {input_length} spectral tiles.') print('\t----------') # Mosaic raster tiles to new raster print(f'\tMosaicking the input rasters for {grid_title}...') iteration_start = time.time() arcpy.management.MosaicToNewRaster(input_rasters, mosaic_location, mosaic_name, output_system, '16_BIT_SIGNED', cell_size, '1', 'MAXIMUM', 'FIRST') # Enforce correct projection arcpy.management.DefineProjection(mosaic_raster, output_system) # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') # Calculate the missing area print('\tCalculating null space...') iteration_start = time.time() raster_null = SetNull(IsNull(Raster(mosaic_raster)), 1, 'VALUE = 1') # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') # Impute missing data by nibbling the NoData from the focal mean print('\tImputing missing values by geographic nearest neighbor...') iteration_start = time.time() raster_filled = Nibble(Raster(mosaic_raster), raster_null, 'DATA_ONLY', 'PROCESS_NODATA', '') # Copy nibble raster to output print(f'\tSaving filled raster...') arcpy.management.CopyRaster(raster_filled, nibble_raster, '', '0', '-32768', 'NONE', 'NONE', '16_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE', 'CURRENT_SLICE', 'NO_TRANSPOSE') # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') # Remove overflow fill from the study area print('\tRemoving overflow fill from study area...') iteration_start = time.time() raster_preliminary = ExtractByMask(nibble_raster, study_area) # Copy preliminary extracted raster to output arcpy.management.CopyRaster(raster_preliminary, spectral_area, '', '0', '-32768', 'NONE', 'NONE', '16_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE', 'CURRENT_SLICE', 'NO_TRANSPOSE') # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') # Remove overflow fill from the grid print('\tRemoving overflow fill from grid...') iteration_start = time.time() raster_final = ExtractByMask(spectral_area, grid_raster) arcpy.management.CopyRaster(raster_final, spectral_grid, '', '0', '-32768', 'NONE', 'NONE', '16_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE', 'CURRENT_SLICE', 'NO_TRANSPOSE') # Delete intermediate rasters if arcpy.Exists(mosaic_raster) == 1: arcpy.management.Delete(mosaic_raster) if arcpy.Exists(nibble_raster) == 1: arcpy.management.Delete(nibble_raster) if arcpy.Exists(spectral_area) == 1: arcpy.management.Delete(spectral_area) # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') out_process = f'Successfully created {os.path.split(spectral_grid)[1]}' return out_process
def get_path_residence_times (in_file, cost_rast, out_raster, t_diff_fld_name, workspace): if len (out_raster) == 0: arcpy.AddError ("Missing argument: out_rast") raise Exception if len (t_diff_fld_name) == 0: t_diff_fld_name = "T_DIFF_HRS" arcpy.env.overwriteOutput = True # This is underhanded. It should be an argument. if arcpy.env.outputCoordinateSystem is None: arcpy.env.outputCoordinateSystem = cost_rast arcpy.AddMessage ("coordinate system is %s" % arcpy.env.outputCoordinateSystem.name) if len(workspace): arcpy.env.workspace = workspace if arcpy.env.workspace is None or len(arcpy.env.workspace) == 0: arcpy.env.workspace = os.getcwd() if '.gdb' in arcpy.env.workspace: arcpy.AddError ( "Worskpace is a geodatabase. " + "This brings too much pain for this script to work.\n" + "%s" % arcpy.env.workspace ) raise WorkspaceIsGeodatabase r = Raster(cost_rast) if r.maximum == 0 and r.minimum == 0: arcpy.AddMessage ('Cost raster has only zero value. Cannot calculate cost distances.') raise CostRasterIsZero size = r.height * r.width * 4 if size > 2 * 1028 ** 3: import struct struct_size = struct.calcsize("P") * 8 if struct_size == 32: size_in_gb = float (size) / (1028 ** 3) arcpy.AddMessage ( 'Cost raster exceeds 2 GiB in size (%s GiB). This is too large for a 32 bit NumPy.' % size_in_gb ) raise NumPyArrayExceedsSizeLimits if not check_points_are_in_cost_raster(in_file, cost_rast): arcpy.AddError ('One or more input points do not intersect the cost raster') raise PointNotOnRaster arcpy.env.snapRaster = cost_rast suffix = None wk = arcpy.env.workspace if not '.gdb' in wk: suffix = '.shp' ext = arcpy.env.extent if ext is None: arcpy.env.extent = r.extent arcpy.AddMessage ("Extent is %s" % arcpy.env.extent) arcpy.env.cellSize = r.meanCellWidth arcpy.AddMessage ("Cell size is %s" % arcpy.env.cellSize) cellsize_used = float (arcpy.env.cellSize) extent = arcpy.env.extent lower_left_coord = extent.lowerLeft arcpy.AddMessage ('Currently in directory: %s\n' % os.getcwd()) arcpy.AddMessage ('Workspace is: %s' % arcpy.env.workspace) arcpy.AddMessage ("lower left is %s" % lower_left_coord) if arcpy.env.mask is None: arcpy.AddMessage ("Setting mask to %s" % cost_rast) arcpy.env.mask = cost_rast # accumulated transits transit_array_accum = arcpy.RasterToNumPyArray (Raster(cost_rast) * 0) feat_layer = "feat_layer" arcmgt.MakeFeatureLayer(in_file, feat_layer) desc = arcpy.Describe (feat_layer) oid_fd_name = desc.OIDFieldName arcpy.AddMessage("oid_fd_name = %s" % oid_fd_name) # variable name is redundant now??? - should all calls be to oid_fd_name? target_fld = oid_fd_name proc_layer = "process_layer" arcmgt.MakeFeatureLayer(in_file, proc_layer) rows = arcpy.SearchCursor(proc_layer) last_target = None for row_cur in rows: transit_time = row_cur.getValue (t_diff_fld_name) if last_target is None or transit_time == 0: message = 'Skipping %s = %s' % (oid_fd_name, row_cur.getValue(oid_fd_name)) if transit_time == 0: message = message + " Transit time is zero" arcpy.AddMessage(message) last_target = row_cur.getValue(target_fld) last_oid = row_cur.getValue(oid_fd_name) continue arcpy.AddMessage ("Processing %s %i" % (oid_fd_name, row_cur.getValue(oid_fd_name))) arcmgt.SelectLayerByAttribute( feat_layer, "NEW_SELECTION", '%s = %s' % (target_fld, last_target) ) backlink_rast = arcpy.CreateScratchName("backlink") path_dist_rast = PathDistance(feat_layer, cost_rast, out_backlink_raster = backlink_rast) # extract the distance from the last point shp = row_cur.shape centroid = shp.centroid (x, y) = (centroid.X, centroid.Y) result = arcmgt.GetCellValue(path_dist_rast, "%s %s" % (x, y), "1") res_val = result.getOutput(0) if res_val == "NoData": this_oid = row_cur.getValue(oid_fd_name) arcpy.AddMessage ("Got nodata for coordinate (%s, %s)" % (x, y)) arcpy.AddMessage ("Is the path between features %s and %s wholly contained by the cost raster?" % (last_oid, this_oid)) pras_name = "pth_%s_%s.tif" % (last_oid, this_oid) arcpy.AddMessage ("Attempting to save path raster as %s" % pras_name) try: path_dist_rast.save(pras_name) except Exception as e: arcpy.AddMessage (e) raise PathDistanceIsNoData try: path_distance = float (res_val) except: # kludge around locale/radix issues if res_val.find(","): res_val = res_val.replace(",", ".") path_distance = float (res_val) else: raise arcpy.AddMessage("Path distance is %s\nTransit time is %s" % (path_distance, transit_time)) # get a raster of the path from origin to destination condition = '%s in (%i, %i)' % (oid_fd_name, last_oid, row_cur.getValue(oid_fd_name)) dest_layer = "dest_layer" + str (last_oid) arcmgt.MakeFeatureLayer(in_file, dest_layer, where_clause = condition) count = arcmgt.GetCount(dest_layer) count = int (count.getOutput(0)) if count == 0: raise NoFeatures("No features selected. Possible coordinate system issues.\n" + condition) try: path_cost_rast = CostPath(dest_layer, path_dist_rast, backlink_rast) #path_dist_rast.save("xx_pr" + str (last_oid)) except Exception as e: raise try: pcr_mask = 1 - IsNull (path_cost_rast) #pcr_mask.save ("xx_pcr_mask" + str (last_oid)) dist_masked = path_dist_rast * pcr_mask path_array = arcpy.RasterToNumPyArray(dist_masked, nodata_to_value = -9999) path_array_idx = numpy.where(path_array > 0) transit_array = numpy.zeros_like(path_array) # past experience suggests we might need to use a different approach to guarantee we get zeroes except: raise path_sum = None arcpy.AddMessage ("processing %i cells of path raster" % (len(path_array_idx[0]))) if path_distance == 0 or not len(path_array_idx[0]): path_sum = 1 # stayed in the same cell mask_array = arcpy.RasterToNumPyArray(pcr_mask, nodata_to_value = -9999) mask_array_idx = numpy.where(mask_array == 1) i = mask_array_idx[0][0] j = mask_array_idx[1][0] transit_array[i][j] = path_sum else: row_count = len (path_array) col_count = len (path_array[0]) for idx in range (len(path_array_idx[0])): i = path_array_idx[0][idx] j = path_array_idx[1][idx] val = path_array[i][j] nbrs = [] for k in (i-1, i, i+1): if k < 0 or k >= row_count: continue checkrow = path_array[k] for l in (j-1, j, j+1): if l < 0 or l >= col_count: continue if k == i and j == l: continue # don't check self checkval = checkrow[l] # negs are nodata, and this way we # don't need to care what that value is if checkval >= 0: diff = val - checkval if diff > 0: nbrs.append(diff) #arcpy.AddMessage ("Check and diff vals are %s %s" % (checkval, diff)) diff = min (nbrs) #arcpy.AddMessage ("Diff val is %s" % diff) transit_array[i][j] = diff path_sum = path_array.max() # could use path_distance? #arcpy.AddMessage ("path_array.max is %s" % path_sum) # sometimes we get a zero path_sum even when the path_distance is non-zero if path_sum == 0: path_sum = 1 # Increment the cumulative transit array by the fraction of the # transit time spent in each cell. # Use path_sum because it corrects for cases where we stayed in the same cell. transit_array_accum = transit_array_accum + ((transit_array / path_sum) * transit_time) #xx = arcpy.NumPyArrayToRaster (transit_array, lower_left_coord, cellsize_used, cellsize_used, 0) #tmpname = "xx_t_arr_" + str (last_oid) #print "Saving transit array to %s" % tmpname #xx.save (tmpname) try: arcmgt.Delete(backlink_rast) arcmgt.Delete(dest_layer) except Exception as e: arcpy.AddMessage (e) # getting off-by-one errors when using the environment, so use this directly ext = path_cost_rast.extent lower_left_coord = ext.lowerLeft last_target = row_cur.getValue(target_fld) last_oid = row_cur.getValue(oid_fd_name) # need to use env settings to get it to be the correct size try: arcpy.AddMessage ("lower left is %s" % lower_left_coord) xx = arcpy.NumPyArrayToRaster (transit_array_accum, lower_left_coord, cellsize_used, cellsize_used, 0) print "Saving to %s" % out_raster xx.save (out_raster) except: raise print "Completed" return ()
def arc_catch_del(WD, boundary_shp, sites_shp, site_num_col='site', point_dis=1000, stream_depth=10, grid_size=8, pour_dis=20, streams='S:/Surface Water/shared\\GIS_base\\vector\\MFE_REC_rivers_no_1st.shp', dem='S:/Surface Water/shared\\GIS_base\\raster\\DEM_8m_2012\\linz_8m_dem', export_dir='results', overwrite_rasters=False): """ Arcpy function to delineate catchments based on specific points, a polygon, and the REC rivers layer. Arcpy must be installed. Be careful that the folder path isn't too long!!! Do not have spaces in the path name!!! Arc sucks!!! Parameters: WD: str Working directory. boundary_shp: str The path to the shapefile polygon boundary extent. sites_shp: str The path to the sites shapefile. site_num_col: str The column in the sites_shp that contains the site IDs. point_dis: int The max distance to snap the sites to the nearest stream line. stream_depth: int The depth that the streams shapefile should be burned into the dem. grid_size: int The resolution of the dem. streams: str The path to the streams shapefile. dem: str The path to the dem. export_dir: str The subfolder where the results should be saved. overwrite_rasters: bool Should the flow direction and flow accumulation rasters be overwritten? Returns ------- None """ # load in the necessary arcpy libraries to import arcpy sys.path.append('C:\\Python27\\ArcGIS10.4\\Lib\\site-packages') sys.path.append(r'C:\Program Files (x86)\ArcGIS\Desktop10.4\arcpy') sys.path.append(r'C:\Program Files (x86)\ArcGIS\Desktop10.4\ArcToolbox\Scripts') sys.path.append(r'C:\Program Files (x86)\ArcGIS\Desktop10.4\bin') sys.path.append('C:\\Python27\\ArcGIS10.4\\lib') # Import packages import arcpy from arcpy import env from arcpy.sa import Raster, Con, IsNull, FlowDirection, FlowAccumulation, Fill, SnapPourPoint, Watershed #import ArcHydroTools as ah # Check out spatial analyst license arcpy.CheckOutExtension('Spatial') # Define functions # def snap_points(points, lines, distance): # # import arcgisscripting, sys # # gp = arcgisscripting.create() # # # Load the Analysis toolbox so that the Near tool is available # gp.toolbox = "analysis" # # # Perform the Near operation looking for the nearest line # # (from the lines Feature Class) to each point (from the # # points Feature Class). The third argument is the search # # radius - blank means to search as far as is needed. The # # fourth argument instructs the command to output the # # X and Y co-ordinates of the nearest point found to the # # NEAR_X and NEAR_Y fields of the points Feature Class # gp.near(points, lines, str(distance), "LOCATION") # # # Create an update cursor for the points Feature Class # # making sure that the NEAR_X and NEAR_Y fields are included # # in the return data # rows = gp.UpdateCursor(points, "", "", "NEAR_X, NEAR_Y") # # row = rows.Next() # # # For each row # while row: # # Get the location of the nearest point on one of the lines # # (added to the file as fields by the Near operation above # new_x = row.GetValue("NEAR_X") # new_y = row.GetValue("NEAR_Y") # # # Create a new point object with the new x and y values # point = gp.CreateObject("Point") # point.x = new_x # point.y = new_y # # # Assign it to the shape field # row.shape = point # # # Update the row data and move to the next row # rows.UpdateRow(row) # row = rows.Next() def snap_points(points, lines, distance): """ Ogi's updated snap_points function. """ points = arcpy.Near_analysis(points, lines, str(distance), "LOCATION") # Create an update cursor for the points Feature Class # making sure that the NEAR_X and NEAR_Y fields are included # in the return data with arcpy.da.UpdateCursor(points, ["NEAR_X", "NEAR_Y", "SHAPE@XY"]) as cursor: for row in cursor: x, y, shape_xy = row shape_xy = (x, y) cursor.updateRow([x, y, shape_xy]) return(points) ### Parameters: ## input # Necessary to change env.workspace = WD boundary = boundary_shp sites_in = sites_shp # site_num_col = 'site' # May not be necessary to change final_export_dir = export_dir # streams = 'S:/Surface Water/shared\\GIS_base\\vector\\MFE_REC_rivers_no_1st.shp' # dem = 'S:/Surface Water/shared\\GIS_base\\raster\\DEM_8m_2012\\linz_8m_dem' env.extent = boundary arcpy.env.overwriteOutput = True ## output bound = 'bound_diss.shp' sites = 'sites_bound.shp' streams_loc = 'MFE_streams_loc.shp' dem_loc = 'dem_loc.tif' stream_diss = 'MFE_rivers_diss.shp' stream_rast = 'stream_rast.tif' dem_diff_tif = 'dem_diff.tif' dem_fill_tif = 'dem_fill.tif' fd_tif = 'fd1.tif' accu_tif = 'accu1.tif' catch_poly = 'catch_del.shp' if not os.path.exists(os.path.join(env.workspace, final_export_dir)): os.makedirs(os.path.join(env.workspace, final_export_dir)) ########################## #### Processing ### Process sites and streams vectors # Dissolve boundary for faster processing arcpy.Dissolve_management(boundary, bound) # Clip sites and streams to boundary arcpy.Clip_analysis(streams, bound, streams_loc) arcpy.Clip_analysis(sites_in, bound, sites) # Snap sites to streams layer snap_points(sites, streams_loc, point_dis) # Dissolve stream network arcpy.Dissolve_management(streams_loc, stream_diss, "", "", "MULTI_PART", "DISSOLVE_LINES") # Add raster parameters to streams layer arcpy.AddField_management(stream_diss, "rast", "SHORT") arcpy.CalculateField_management(stream_diss, "rast", stream_depth, "PYTHON_9.3") ############################################ ### Delineate catchments # Convert stream vector to raster arcpy.FeatureToRaster_conversion(stream_diss, 'rast', stream_rast, grid_size) ## Create the necessary flow direction and accumulation rasters if they do not already exist if os.path.exists(os.path.join(env.workspace, accu_tif)) & (not overwrite_rasters): accu1 = Raster(accu_tif) fd1 = Raster(fd_tif) else: # Clip the DEM to the study area print('clipping DEM to catchment area...') arcpy.Clip_management(dem, "1323813.1799 5004764.9257 1688157.0305 5360238.95", dem_loc, bound, "", "ClippingGeometry", "NO_MAINTAIN_EXTENT") # Fill holes in DEM print('Filling DEM...') # dem_fill = Fill(dem_loc) # Subtract stream raster from s_rast = Raster(stream_rast) dem_diff = Con(IsNull(s_rast), dem_loc, dem_loc - s_rast) dem_diff.save(dem_diff_tif) # Fill holes in DEM dem2 = Fill(dem_diff_tif) dem2.save(dem_fill_tif) # flow direction print('Flow direction...') fd1 = FlowDirection(dem2) fd1.save(fd_tif) # flow accu print('Flow accumulation...') accu1 = FlowAccumulation(fd1) accu1.save(accu_tif) # create pour points pp1 = SnapPourPoint(sites, accu1, pour_dis, site_num_col) # Determine the catchments for all points catch1 = Watershed(fd1, pp1) # Convert raster to polygon arcpy.RasterToPolygon_conversion(catch1, catch_poly, 'SIMPLIFY', 'Value') # Add in a field for the area of each catchment arcpy.AddField_management(catch_poly, "area_m2", "LONG") arcpy.CalculateField_management(catch_poly, "area_m2", 'round(!shape.area!)', "PYTHON_9.3") #### Check back in the spatial analyst license once done arcpy.CheckInExtension('Spatial')
def convert_fire_history(**kwargs): """ Description: converts fire history polygons to rasters and extracts to major grid and study area Inputs: 'work_geodatabase' -- path to a file geodatabase that will serve as the workspace 'input_array' -- an array containing the target feature class to convert (must be first), the study area raster (must be second), and the grid raster (must be third) 'output_array' -- an array containing the output raster Returned Value: Returns a raster dataset Preconditions: the target feature class must be created using the recent fire history function """ # Import packages import arcpy from arcpy.sa import Con from arcpy.sa import ExtractByMask from arcpy.sa import IsNull from arcpy.sa import Raster import datetime import time import os # Parse key word argument inputs work_geodatabase = kwargs['work_geodatabase'] input_feature = kwargs['input_array'][0] study_area = kwargs['input_array'][1] grid_raster = kwargs['input_array'][2] output_raster = kwargs['output_array'][0] # Set overwrite option arcpy.env.overwriteOutput = True # Set workspace arcpy.env.workspace = work_geodatabase # Set snap raster and extent arcpy.env.snapRaster = study_area arcpy.env.extent = Raster(grid_raster).extent arcpy.env.cellSize = 'MINOF' # Define intermediate rasters convert_raster = os.path.splitext(output_raster)[0] + '.tif' # Convert fire history feature class to raster print('\tConverting feature class to raster within grid...') iteration_start = time.time() arcpy.conversion.PolygonToRaster(input_feature, 'FireYear', convert_raster, 'CELL_CENTER', 'FireYear', 10) # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})') print('\t----------') # Convert no data values to zero print('\tConverting no data to zero...') iteration_start = time.time() zero_raster = Con(IsNull(Raster(convert_raster)), 0, Raster(convert_raster)) # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})') print('\t----------') # Extract raster to study area print(f'\tExtracting raster to grid...') iteration_start = time.time() extract1_raster = ExtractByMask(zero_raster, grid_raster) print(f'\tExtracting raster to study area...') extract2_raster = ExtractByMask(extract1_raster, study_area) print(f'\tCopying extracted raster to new raster...') arcpy.management.CopyRaster(extract2_raster, output_raster, '', '', '-32768', 'NONE', 'NONE', '16_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE', 'CURRENT_SLICE', 'NO_TRANSPOSE' ) # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Report success print(f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})') print('\t----------') out_process = f'Successfully extracted recent fire history to study area.' return out_process
def main(): # GET PARAMETER VALUES Map_Units_Provided = arcpy.GetParameterAsText(0) # DEFINE DIRECTORIES # Get the pathname to this script scriptPath = sys.path[0] arcpy.AddMessage("Script folder: " + scriptPath) arcpy.AddMessage("Python version: " + sys.version) # Construct pathname to workspace projectGDB = arcpy.Describe(Map_Units_Provided).path arcpy.AddMessage("Project geodatabase: " + projectGDB) # Instantiate a idStandard object cheStandard = cohqt.cheStandard(projectGDB, scriptPath) # ENVIRONMENT SETTINGS # Set workspaces arcpy.env.workspace = projectGDB scratch_folder = os.path.join(arcpy.Describe(projectGDB).path, 'scratch') if arcpy.Exists(scratch_folder): pass else: arcpy.CreateFolder_management(scratch_folder) arcpy.env.scratchWorkspace = scratch_folder # Overwrite outputs arcpy.env.overwriteOutput = True # DEFINE GLOBAL VARIABLES cell_size = 30 inputDataPath = cheStandard.InputDataPath GrSG_Habitat = cheStandard.GrSGHabitatRaster ConiferModifier = cheStandard.ConiferModifier GrSG_LDI = cheStandard.GrSG_LDI LekPresenceRaster = cheStandard.LekPresenceRaster Lek_Distance_Modifier = cheStandard.LekDistanceModifier SageModifier = cheStandard.SageModifier GrSG_Habitat = cheStandard.BWSGHab # Filenames of feature classes and rasters used by this script MAP_UNITS = "Map_Units" PROPOSED_SURFACE_DISTURBANCE_DEBITS = "Proposed_Surface_Disturbance_Debits" DISTURBED_FOOTPRINT = "Disturbed_Footprint" CURRENT_ANTHRO_FEATURES = "Current_Anthro_Features" CURRENT_ANTHRO_DISTURBANCE = "GrSG_Pre_Anthro_Disturbance" PROJECTED_ANTHRO_DISTURBANCE = "GRSG_Post_Anthro_Disturbance" LEK_DISTURBANCE_MODIFIER = "Lek_Disturbance_Modifier" DEBIT_PROJECT_AREA = "Debit_Project_Area" DEBIT_PROJECT_IMPACT_A = "Debit_Project_Impact_Adjusted" # Filenames of feature classes and rasters created by this script # GrSG Filenames GRSG_PRE_BREEDING_A = "GRSG_Pre_Breeding_adjusted" GRSG_PRE_SUMMER_A = "GRSG_Pre_Summer_adjusted" GRSG_PRE_WINTER_A = "GRSG_Pre_Winter_adjusted" GRSG_POST_BREEDING_A = "GRSG_Post_Breeding_adjusted" GRSG_POST_SUMMER_A = "GRSG_Post_Summer_adjusted" GRSG_POST_WINTER_A = "GRSG_Post_Winter_adjusted" CUMULATIVE_MODIFIER_PRE_A = "GRSG_Pre_Cumulative_Modifier_adjusted" CUMULATIVE_MODIFIER_POST_A = "GRSG_Post_Cumulative_Modifier_adjusted" # ------------------------------------------------------------------------ # FUNCTION CALLS # Check out Spatial Analyst extension hqtlib.CheckOutSpatialAnalyst() # Clear selection, if present util.ClearSelectedFeatures(Map_Units_Provided) # Check Map_Units layer feature = Map_Units_Provided required_fields = ["Map_Unit_ID", "Map_Unit_Name"] no_null_fields = ["Map_Unit_ID"] expected_fcs = None hqtlib.CheckPolygonInput(feature, required_fields, expected_fcs, no_null_fields) # Update Map Units layer with provided layer and add to map Map_Units = util.AdoptParameter(Map_Units_Provided, MAP_UNITS, preserve_existing=False) layerFile = cheStandard.getLayerFile("MapUnits.lyr") util.AddToMap(Map_Units, layerFile) # # Udpate message # arcpy.AddMessage("Dissolving all multi-part map units to create " # "Map_Units_Dissolve") # # Dissolve Map Units # allowable_fields = ["Map_Unit_ID", "Map_Unit_Name", "Notes", # "Disturbance_Type", "Precip", ] # out_name = MAP_UNITS_DISSOLVE # anthro_features = CURRENT_ANTHRO_FEATURES # Map_Units_Dissolve = hqtlib.DissolveMapUnits(MUs, allowable_fields, # out_name, anthro_features) # # Update message # arcpy.AddMessage("Adding Map_Units_Dissolve to map") # # Add layer to map document # feature = Map_Units_Dissolve # layerFile = cheStandard.getLayerFile("Map_Units.lyr") # util.AddToMap(feature, layerFile) # # Update message # arcpy.AddMessage("Calculating area in acres for each map unit") # # Calculate Area # hqtlib.CalcAcres(Map_Units_Dissolve) # Update message arcpy.AddMessage("Creating site-scale habitat quality rasters") # # ADD Join from Excel Doc # out_table = os.path.join(projectGDB, "Site_Scale_Scores") # summary_table = arcpy.ExcelToTable_conversion(Debit_Calculator, # out_table, # "Summary") # arcpy.AddJoin_management(Map_Units, "Map_Unit_ID", # summary_table, "MapUnitID") # Convert Map Units to raster of Habitat Quality (0 - 1 scale) and mask # out BWSG habitat seasonsList = cheStandard.GrSGSeasons for season in seasonsList: mu_raster_path = cohqt.convertMapUnitsToRaster(projectGDB, Map_Units, season, cell_size) mu_raster = Raster(mu_raster_path) # Mask out BWSG habitat SuitableHabitat_adjusted = Con(IsNull(Float(mu_raster)), GrSG_Habitat, Float(mu_raster)) SuitableHabitat_adjusted.save( os.path.join(projectGDB, season + "_Habitat_adjusted")) # Update message arcpy.AddMessage("Calculating Pre-Project Habitat Modifiers") # Re-run fron calcWinterHabitat down with updated BWSG layer (append # "_adjusted") WinterSuitableHabitat = os.path.join(projectGDB, "Winter_Habitat_adjusted") winterHabitatPre = cohqt.calcWinterHabitatGRSG(CURRENT_ANTHRO_DISTURBANCE, ConiferModifier, GrSG_LDI, WinterSuitableHabitat) LSDMWinterPre = cohqt.applyLekUpliftModifierPre(winterHabitatPre, LekPresenceRaster) BreedingSuitableHabitat = os.path.join(projectGDB, "Breed_Habitat_adjusted") breedingHabitatPre = cohqt.calcBreedingHabitatGRSG( CURRENT_ANTHRO_DISTURBANCE, ConiferModifier, GrSG_LDI, Lek_Distance_Modifier, BreedingSuitableHabitat) LSDMBreedingPre = cohqt.applyLekUpliftModifierPre(breedingHabitatPre, LekPresenceRaster) SummerSuitableHabitat = os.path.join(projectGDB, "Summer_Habitat_adjusted") summerHabitatPre = cohqt.calcSummerHabitatGRSG(CURRENT_ANTHRO_DISTURBANCE, ConiferModifier, GrSG_LDI, SageModifier, SummerSuitableHabitat) LSDMSummerPre = cohqt.applyLekUpliftModifierPre(summerHabitatPre, LekPresenceRaster) seasonalHabitatRasters = [LSDMWinterPre, LSDMBreedingPre, LSDMSummerPre] # Save outputs # winterHabitatPre.save("Pre_Seasonal_Winter_adjusted") LSDMWinterPre.save(GRSG_PRE_WINTER_A) # breedingHabitatPre.save("Pre_Seasonal_Breeding_adjusted") LSDMBreedingPre.save(GRSG_PRE_BREEDING_A) # summerHabitatPre.save("Pre_Seasonal_Summer_adjusted") LSDMSummerPre.save(GRSG_PRE_SUMMER_A) # Calculate average of three seasonal habitat rasters pre-project finalPreCumulative = cohqt.calcAverageHabitatQuality( seasonalHabitatRasters) finalPreCumulative.save(CUMULATIVE_MODIFIER_PRE_A) # Calculate post-project cumulative habtiat modifiers winterHabitatPost = cohqt.calcWinterHabitatGRSG( PROJECTED_ANTHRO_DISTURBANCE, ConiferModifier, GrSG_LDI, WinterSuitableHabitat) LSDMWinterPost = cohqt.applyLekUpliftModifierPost( winterHabitatPost, LekPresenceRaster, LEK_DISTURBANCE_MODIFIER) breedingHabitatPost = cohqt.calcBreedingHabitatGRSG( PROJECTED_ANTHRO_DISTURBANCE, ConiferModifier, GrSG_LDI, Lek_Distance_Modifier, BreedingSuitableHabitat) LSDMBreedingPost = cohqt.applyLekUpliftModifierPost( breedingHabitatPost, LekPresenceRaster, LEK_DISTURBANCE_MODIFIER) summerHabitatPost = cohqt.calcSummerHabitatGRSG( PROJECTED_ANTHRO_DISTURBANCE, ConiferModifier, GrSG_LDI, SageModifier, SummerSuitableHabitat) LSDMSummerPost = cohqt.applyLekUpliftModifierPost( summerHabitatPost, LekPresenceRaster, LEK_DISTURBANCE_MODIFIER) seasonalHabitatRasters = [LSDMWinterPost, LSDMBreedingPost, LSDMSummerPost] # Save outputs # winterHabitatPost.save("Post_Seasonal_Winter") LSDMWinterPost.save(GRSG_POST_WINTER_A) # breedingHabitatPost.save("Post_Seasonal_Breeding") LSDMBreedingPost.save(GRSG_POST_BREEDING_A) # summerHabitatPost.save("Post_Seasonal_Summer") LSDMSummerPost.save(GRSG_POST_SUMMER_A) # Calculate average of three seasonal habitat rasters post-project finalPostCumulative = cohqt.calcAverageHabitatQuality( seasonalHabitatRasters) finalPostCumulative.save(CUMULATIVE_MODIFIER_POST_A) # Calculate Zonal Statistics for cumulative modifier rasters # Calculate zonal statistics for pre-project inZoneData = DEBIT_PROJECT_AREA inValueRaster = finalPreCumulative zoneField = "ZONAL" outTable = "GRSG_Stats_Pre_adjusted" hqtlib.CalcZonalStats(inZoneData, zoneField, inValueRaster, outTable) # Join the zonal statistic to the Debit Project Area table fieldName = "GRSG_Pre_Project_A" hqtlib.JoinMeanToTable(inZoneData, outTable, zoneField, fieldName) # Calculate zonal statistics for post-project inZoneData = DEBIT_PROJECT_AREA inValueRaster = finalPostCumulative zoneField = "ZONAL" outTable = "GRSG_Stats_Post_adjusted" hqtlib.CalcZonalStats(inZoneData, zoneField, inValueRaster, outTable) # Join the zonal statistic to the Debit Project Area table fieldName = "GrSG_Post_Project_A" hqtlib.JoinMeanToTable(inZoneData, outTable, zoneField, fieldName) # Calculate debits using field data cohqt.calcDebits(DEBIT_PROJECT_AREA, "GRSG_Pre_Project_A", "GrSG_Post_Project_A", "Debits_adj") # Update message arcpy.AddMessage("Creating visualization of impact from debit project") # Calculate impact intensity for debit project debit_impact = cohqt.calcImpact(finalPreCumulative, finalPostCumulative) debit_impact.save(DEBIT_PROJECT_IMPACT_A) # Add Debit Impact raster to map and save map document feature = debit_impact layerFile = cheStandard.getLayerFile("DebitProjectImpact.lyr") util.AddToMap(feature, layerFile, zoom_to=True) # Clean up arcpy.Delete_management("in_memory") # Save map document if arcpy.ListInstallations()[0] == 'arcgispro': p = arcpy.mp.ArcGISProject("CURRENT") p.save() else: mxd = arcpy.mapping.MapDocument("CURRENT") mxd.save()
def convertProposedToRasterCredit(anthroFeaturesRemoved, cellSize): arcpy.AddMessage("Preparing Proposed Surface Disturbance for processing") # Add field Conifer to use when converting to raster inTable = anthroFeaturesRemoved fieldName = "Weight2" fieldType = "SHORT" expression = 1 arcpy.AddField_management(inTable, fieldName, fieldType) arcpy.CalculateField_management(inTable, fieldName, expression, "PYTHON_9.3", "") # Check feature type of provided feature class desc = arcpy.Describe(anthroFeaturesRemoved) # Make feature layer of proposed surface disturbance features = arcpy.MakeFeatureLayer_management(anthroFeaturesRemoved, "lyr") # Generate list of unique subtypes in Proposed_Surface_Disturbance uniqueProposedSubtypes = list(set([row[0] for row in arcpy.da.SearchCursor( anthroFeaturesRemoved, "Subtype")])) arcpy.AddMessage("Proposed Surface Disturbance contains " + ", ".join(uniqueProposedSubtypes)) for subtype in uniqueProposedSubtypes: # Select features of specified subtype field = "Subtype" where_clause = """{} = '{}'""".format(arcpy.AddFieldDelimiters (features, field), subtype) arcpy.SelectLayerByAttribute_management(features, "NEW_SELECTION", where_clause) # Count features selected to ensure >0 feature selected test = arcpy.GetCount_management(features) count = int(test.getOutput(0)) # Convert to raster if count > 0: in_features = features value_field = "Weight" out_rasterdataset = os.path.join("in_memory", "Proposed_" + subtype + "Null") cell_assignment = "MAXIMUM_AREA" priority_field = "Weight" if desc.shapeType == "Polygon": arcpy.PolygonToRaster_conversion(in_features, value_field, out_rasterdataset, cell_assignment, priority_field, cellSize) else: # Consider changing to buffer of ? meters arcpy.FeatureToRaster_conversion(in_features, value_field, out_rasterdataset, cellSize) # Change Null values to 0 in proposed anthro feature removed raster out_con = Con(IsNull(out_rasterdataset), 0, out_rasterdataset) out_con.save("Proposed_" + subtype) # Clear selected features arcpy.SelectLayerByAttribute_management(features, "CLEAR_SELECTION") return uniqueProposedSubtypes
def interpolate_raster(**kwargs): """ Description: interpolates missing raster data using nearest existing raster data Inputs: 'input_array' -- an array containing the study area raster (must be first) and the climate raster (last) 'output_array' -- an array containing the output climate raster for the grid Returned Value: Returns a raster dataset on disk containing the combined climate property for a grid Preconditions: requires an input grid raster and climate property raster """ # Import packages import arcpy from arcpy.sa import IsNull from arcpy.sa import Nibble from arcpy.sa import Raster from arcpy.sa import SetNull import datetime import time # Parse key word argument inputs study_area = kwargs['input_array'][0] climate_raster = kwargs['input_array'][1] output_raster = kwargs['output_array'][0] # Set overwrite option arcpy.env.overwriteOutput = True # Set snap raster and extent arcpy.env.snapRaster = climate_raster arcpy.env.cellSize = 'MINOF' arcpy.env.extent = Raster(study_area).extent # Interpolate missing data from the climate raster print('\tCalculating null space...') iteration_start = time.time() raster_null = SetNull(IsNull(Raster(climate_raster)), 1, 'VALUE = 1') print(f'\tInterpolating missing data...') nibble_raster = Nibble(Raster(climate_raster), raster_null, 'DATA_ONLY', 'PROCESS_NODATA', '') # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') # Export interpolated raster to output raster print(f'\tExporting interpolated raster to output raster...') iteration_start = time.time() arcpy.management.CopyRaster(nibble_raster, output_raster, '', '', '-32768', 'NONE', 'NONE', '16_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE') # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') out_process = f'Finished interpolating raster.' return out_process
def calculate_topographic_properties(**kwargs): """ Description: calculates topographic properties from an elevation raster Inputs: 'z_unit' -- a string value of either 'Meter' or 'Foot' representing the vertical unit of the elevation raster 'input_array' -- an array containing the grid raster (must be first) and the elevation raster 'output_array' -- an array containing the output rasters for aspect, compound topographic index, heat load index, integrated moisture index, roughness, site exposure, slope, surface area ratio, and surface relief ratio (in that order) Returned Value: Returns a raster dataset on disk for each topographic property Preconditions: requires an input DEM that can be created through other scripts in this repository """ # Import packages import arcpy from arcpy.sa import Con from arcpy.sa import IsNull from arcpy.sa import ExtractByMask from arcpy.sa import Raster from arcpy.sa import Int from arcpy.sa import FlowDirection from arcpy.sa import FlowAccumulation from arcpy.sa import Slope from arcpy.sa import Aspect from package_Geomorphometry import compound_topographic from package_Geomorphometry import getZFactor from package_Geomorphometry import linear_aspect from package_Geomorphometry import mean_slope from package_Geomorphometry import roughness from package_Geomorphometry import site_exposure from package_Geomorphometry import surface_area from package_Geomorphometry import surface_relief from package_Geomorphometry import topographic_position from package_Geomorphometry import topographic_radiation import datetime import os import time # Parse key word argument inputs z_unit = kwargs['z_unit'] grid_raster = kwargs['input_array'][0] elevation_input = kwargs['input_array'][1] elevation_output = kwargs['output_array'][0] aspect_output = kwargs['output_array'][1] cti_output = kwargs['output_array'][2] roughness_output = kwargs['output_array'][3] exposure_output = kwargs['output_array'][4] slope_output = kwargs['output_array'][5] area_output = kwargs['output_array'][6] relief_output = kwargs['output_array'][7] position_output = kwargs['output_array'][8] radiation_output = kwargs['output_array'][9] # Set overwrite option arcpy.env.overwriteOutput = True # Use two thirds of cores on processes that can be split. arcpy.env.parallelProcessingFactor = "75%" # Set snap raster and extent arcpy.env.snapRaster = grid_raster arcpy.env.extent = Raster(grid_raster).extent # Define folder structure grid_title = os.path.splitext(os.path.split(grid_raster)[1])[0] raster_folder = os.path.split(elevation_output)[0] intermediate_folder = os.path.join(raster_folder, 'intermediate') # Create raster folder if it does not already exist if os.path.exists(raster_folder) == 0: os.mkdir(raster_folder) # Create intermediate folder if it does not already exist if os.path.exists(intermediate_folder) == 0: os.mkdir(intermediate_folder) # Define intermediate datasets flow_direction_raster = os.path.join(intermediate_folder, 'flow_direction.tif') flow_accumulation_raster = os.path.join(intermediate_folder, 'flow_accumulation.tif') raw_slope_raster = os.path.join(intermediate_folder, 'raw_slope.tif') raw_aspect_raster = os.path.join(intermediate_folder, 'raw_aspect.tif') # Get the z factor appropriate to the xy and z units zFactor = getZFactor(elevation_input, z_unit) #### CALCULATE INTERMEDIATE DATASETS # Calculate flow direction if it does not already exist if os.path.exists(flow_direction_raster) == 0: # Calculate flow direction print(f'\tCalculating flow direction for {grid_title}...') iteration_start = time.time() flow_direction = FlowDirection(elevation_input, 'NORMAL', '', 'D8') flow_direction.save(flow_direction_raster) # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') else: print(f'\tFlow direction already exists for {grid_title}.') print('\t----------') # Calculate flow accumulation if it does not already exist if os.path.exists(flow_accumulation_raster) == 0: # Calculate flow accumulation print(f'\tCalculating flow accumulation for {grid_title}...') iteration_start = time.time() flow_accumulation = FlowAccumulation(flow_direction_raster, '', 'FLOAT', 'D8') flow_accumulation.save(flow_accumulation_raster) # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') else: print(f'\tFlow accumulation already exists for {grid_title}.') print('\t----------') # Calculate raw slope in degrees if it does not already exist if os.path.exists(raw_slope_raster) == 0: # Calculate slope print(f'\tCalculating raw slope for {grid_title}...') iteration_start = time.time() raw_slope = Slope(elevation_input, "DEGREE", zFactor) raw_slope.save(raw_slope_raster) # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') else: print(f'\tRaw slope already exists for {grid_title}.') print('\t----------') # Calculate raw aspect if it does not already exist if os.path.exists(raw_aspect_raster) == 0: # Calculate aspect print(f'\tCalculating raw aspect for {grid_title}...') iteration_start = time.time() raw_aspect = Aspect(elevation_input, 'PLANAR', z_unit) raw_aspect.save(raw_aspect_raster) # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') else: print(f'\tRaw aspect already exists for {grid_title}.') print('\t----------') #### CALCULATE INTEGER ELEVATION # Calculate integer elevation if it does not already exist if arcpy.Exists(elevation_output) == 0: print(f'\tCalculating integer elevation for {grid_title}...') iteration_start = time.time() # Round to integer print(f'\t\tConverting values to integers...') integer_elevation = Int(Raster(elevation_input) + 0.5) # Copy extracted raster to output print(f'\t\tCreating output raster...') arcpy.management.CopyRaster(integer_elevation, elevation_output, '', '', '-32768', 'NONE', 'NONE', '16_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE') # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') else: print(f'\tInteger elevation already exists for {grid_title}.') print('\t----------') #### CALCULATE LINEAR ASPECT # Calculate linear aspect if it does not already exist if arcpy.Exists(aspect_output) == 0: print(f'\tCalculating linear aspect for {grid_title}...') iteration_start = time.time() # Create an initial linear aspect calculation using the linear aspect function aspect_intermediate = os.path.splitext( aspect_output)[0] + '_intermediate.tif' linear_aspect(raw_aspect_raster, aspect_intermediate) # Round to integer print(f'\t\tConverting values to integers...') integer_aspect = Int(Raster(aspect_intermediate) + 0.5) # Fill missing data (no aspect) with values of -1 print(f'\t\tFilling values of no aspect...') conditional_aspect = Con(IsNull(integer_aspect), -1, integer_aspect) # Extract filled raster to grid mask print(f'\t\tExtracting filled raster to grid...') extract_aspect = ExtractByMask(conditional_aspect, grid_raster) # Copy extracted raster to output print(f'\t\tCreating output raster...') arcpy.management.CopyRaster(extract_aspect, aspect_output, '', '', '-32768', 'NONE', 'NONE', '16_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE') # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Delete intermediate dataset if possible try: arcpy.management.Delete(aspect_intermediate) except: print('\t\tCould not delete intermediate dataset...') # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') else: print(f'\tLinear aspect already exists for {grid_title}.') print('\t----------') #### CALCULATE COMPOUND TOPOGRAPHIC INDEX # Calculate compound topographic index if it does not already exist if arcpy.Exists(cti_output) == 0: print(f'\tCalculating compound topographic index for {grid_title}...') iteration_start = time.time() # Create an intermediate compound topographic index calculation cti_intermediate = os.path.splitext( cti_output)[0] + '_intermediate.tif' compound_topographic(elevation_input, flow_accumulation_raster, raw_slope_raster, cti_intermediate) # Convert to integer values print(f'\t\tConverting values to integers...') integer_compound = Int((Raster(cti_intermediate) * 100) + 0.5) # Copy integer raster to output print(f'\t\tCreating output raster...') arcpy.management.CopyRaster(integer_compound, cti_output, '', '', '-32768', 'NONE', 'NONE', '16_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE') # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Delete intermediate dataset if possible try: arcpy.management.Delete(cti_intermediate) except: print('\t\tCould not delete intermediate dataset...') # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') else: print(f'\tCompound topographic index already exists for {grid_title}.') print('\t----------') #### CALCULATE ROUGHNESS # Calculate roughness if it does not already exist if arcpy.Exists(roughness_output) == 0: print(f'\tCalculating roughness for {grid_title}...') iteration_start = time.time() # Create an intermediate compound topographic index calculation roughness_intermediate = os.path.splitext( roughness_output)[0] + '_intermediate.tif' roughness(elevation_input, roughness_intermediate) # Convert to integer values print(f'\t\tConverting values to integers...') integer_roughness = Int(Raster(roughness_intermediate) + 0.5) # Fill missing data (no aspect) with values of 0 print(f'\t\tFilling values of roughness...') conditional_roughness = Con(IsNull(integer_roughness), 0, integer_roughness) # Extract filled raster to grid mask print(f'\t\tExtracting filled raster to grid...') extract_roughness = ExtractByMask(conditional_roughness, grid_raster) # Copy extracted raster to output print(f'\t\tCreating output raster...') arcpy.management.CopyRaster(extract_roughness, roughness_output, '', '', '-32768', 'NONE', 'NONE', '16_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE') # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Delete intermediate dataset if possible try: arcpy.management.Delete(roughness_intermediate) except: print('\t\tCould not delete intermediate dataset...') # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') else: print(f'\tRoughness already exists for {grid_title}.') print('\t----------') #### CALCULATE SITE EXPOSURE # Calculate site exposure if it does not already exist if arcpy.Exists(exposure_output) == 0: print(f'\tCalculating site exposure for {grid_title}...') iteration_start = time.time() # Create an intermediate compound topographic index calculation exposure_intermediate = os.path.splitext( exposure_output)[0] + '_intermediate.tif' site_exposure(raw_aspect_raster, raw_slope_raster, exposure_intermediate) # Convert to integer values print(f'\t\tConverting values to integers...') integer_exposure = Int((Raster(exposure_intermediate) * 100) + 0.5) # Copy extracted raster to output print(f'\t\tCreating output raster...') arcpy.management.CopyRaster(integer_exposure, exposure_output, '', '', '-32768', 'NONE', 'NONE', '16_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE') # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Delete intermediate dataset if possible try: arcpy.management.Delete(exposure_intermediate) except: print('\t\tCould not delete intermediate dataset...') # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') else: print(f'\tSite exposure already exists for {grid_title}.') print('\t----------') #### CALCULATE MEAN SLOPE # Calculate mean slope if it does not already exist if arcpy.Exists(slope_output) == 0: print(f'\tCalculating mean slope for {grid_title}...') iteration_start = time.time() # Create an intermediate mean slope calculation slope_intermediate = os.path.splitext( slope_output)[0] + '_intermediate.tif' mean_slope(raw_slope_raster, slope_intermediate) # Convert to integer values print(f'\t\tConverting values to integers...') integer_slope = Int(Raster(slope_intermediate) + 0.5) # Copy extracted raster to output print(f'\t\tCreating output raster...') arcpy.management.CopyRaster(integer_slope, slope_output, '', '', '-128', 'NONE', 'NONE', '8_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE') # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Delete intermediate dataset if possible try: arcpy.management.Delete(slope_intermediate) except: print('\t\tCould not delete intermediate dataset...') # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') else: print(f'\tMean slope already exists for {grid_title}.') print('\t----------') #### CALCULATE SURFACE AREA RATIO # Calculate surface area ratio if it does not already exist if os.path.exists(area_output) == 0: print(f'\tCalculating surface area ratio for {grid_title}...') iteration_start = time.time() # Create an intermediate surface area ratio calculation area_intermediate = os.path.splitext( area_output)[0] + '_intermediate.tif' surface_area(raw_slope_raster, area_intermediate) # Convert to integer values print(f'\t\tConverting values to integers...') integer_area = Int((Raster(area_intermediate) * 10) + 0.5) # Copy extracted raster to output print(f'\t\tCreating output raster...') arcpy.management.CopyRaster(integer_area, area_output, '', '', '-32768', 'NONE', 'NONE', '16_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE') # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Delete intermediate dataset if possible try: arcpy.management.Delete(area_intermediate) except: print('\t\tCould not delete intermediate dataset...') # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') else: print(f'\tSurface area ratio already exists for {grid_title}.') print('\t----------') #### CALCULATE SURFACE RELIEF RATIO # Calculate surface relief ratio if it does not already exist if arcpy.Exists(relief_output) == 0: print(f'\tCalculating surface relief ratio for {grid_title}...') iteration_start = time.time() # Create an intermediate surface relief ratio calculation relief_intermediate = os.path.splitext( relief_output)[0] + '_intermediate.tif' surface_relief(elevation_input, relief_intermediate) # Convert to integer values print(f'\t\tConverting values to integers...') integer_relief = Int((Raster(relief_intermediate) * 1000) + 0.5) # Copy extracted raster to output print(f'\t\tCreating output raster...') arcpy.management.CopyRaster(integer_relief, relief_output, '', '', '-32768', 'NONE', 'NONE', '16_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE') # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Delete intermediate dataset if possible try: arcpy.management.Delete(relief_intermediate) except: print('\t\tCould not delete intermediate dataset...') # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') else: print(f'\tSurface relief ratio already exists for {grid_title}.') print('\t----------') #### CALCULATE TOPOGRAPHIC POSITION # Calculate topographic position if it does not already exist if arcpy.Exists(position_output) == 0: print(f'\tCalculating topographic position for {grid_title}...') iteration_start = time.time() # Create an intermediate topographic position calculation position_intermediate = os.path.splitext( position_output)[0] + '_intermediate.tif' topographic_position(elevation_input, position_intermediate) # Convert to integer values print(f'\t\tConverting values to integers...') integer_position = Int((Raster(position_intermediate) * 100) + 0.5) # Copy extracted raster to output print(f'\t\tCreating output raster...') arcpy.management.CopyRaster(integer_position, position_output, '', '', '-32768', 'NONE', 'NONE', '16_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE') # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Delete intermediate dataset if possible try: arcpy.management.Delete(position_intermediate) except: print('\t\tCould not delete intermediate dataset...') # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') else: print(f'\tTopographic position already exists for {grid_title}.') print('\t----------') #### CALCULATE TOPOGRAPHIC RADIATION # Calculate topographic radiation if it does not already exist if arcpy.Exists(radiation_output) == 0: print(f'\tCalculating topographic radiation for {grid_title}...') iteration_start = time.time() # Create an intermediate topographic position calculation radiation_intermediate = os.path.splitext( radiation_output)[0] + '_intermediate.tif' radiation_integer = os.path.splitext( radiation_output)[0] + '_integer.tif' topographic_radiation(elevation_input, radiation_intermediate) # Convert to integer values print(f'\t\tConverting values to integers...') integer_radiation = Int((Raster(radiation_intermediate) * 1000) + 0.5) arcpy.management.CopyRaster(integer_radiation, radiation_integer, '', '', '-32768', 'NONE', 'NONE', '16_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE') # Extract filled raster to grid mask print(f'\t\tExtracting integer raster to grid...') extract_radiation = ExtractByMask(radiation_integer, grid_raster) # Copy extracted raster to output print(f'\t\tCreating output raster...') arcpy.management.CopyRaster(extract_radiation, radiation_output, '', '', '-32768', 'NONE', 'NONE', '16_BIT_SIGNED', 'NONE', 'NONE', 'TIFF', 'NONE') # End timing iteration_end = time.time() iteration_elapsed = int(iteration_end - iteration_start) iteration_success_time = datetime.datetime.now() # Delete intermediate dataset if possible try: arcpy.management.Delete(radiation_intermediate) arcpy.management.Delete(radiation_integer) except: print('\t\tCould not delete intermediate dataset...') # Report success print( f'\tCompleted at {iteration_success_time.strftime("%Y-%m-%d %H:%M")} (Elapsed time: {datetime.timedelta(seconds=iteration_elapsed)})' ) print('\t----------') else: print(f'\tTopographic radiation already exists for {grid_title}.') print('\t----------') outprocess = f'Finished topographic properties for {grid_title}.' return outprocess