SLC = os.path.join(folder, SLC) distance_raster = arcpy.sa.CostDistance(SLC, cost_raster_file, 200000000, backlinkFile) distance_raster.save(os.path.join(temp, "distance_raster.tif")) arcpy.AddMessage("cost distance raster: done!") #now get the path LV = os.path.join(folder, LV) path_raster = arcpy.sa.CostPath(LV, distance_raster, backlinkFile) path_raster.save(os.path.join(temp, "path_raster.tif")) arcpy.AddMessage("cost path raster: done!") #now convert the path to polyline leastCostPath = os.path.join(temp, "least_cost_path.shp") arcpy.RasterToPolyline_conversion(path_raster, leastCostPath) arcpy.AddMessage("least cost path: done!") #update the path displayed in the current map document mxd = arcpy.mapping.MapDocument(os.path.join(folder, "leastcost.mxd")) add_path_to_map(mxd, leastCostPath) #update the weights label and the title for e in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT"): if e.name == "txtWeights": e.text = "Elevation: %s Slope: %s Road: %s Rail: %s River: %s Lake: %s" \ % (elevWeight, slopeWeight, roadWeight, railWeight, riverWeight, lakeWeight) if e.name == "txtTitle": e.text = "SLC to LV Railroad: " + outputFolderName
def vb_prep(input_dem, output_folder, fill = True, no_data = 0, flow_initiation_threshold = 150000, mask = False): #Setup the directories and paths intermediate_folder = output_folder + 'Intermediate/' if os.path.exists(intermediate_folder ) == False: os.makedirs(intermediate_folder) out_base = output_folder + os.path.splitext(os.path.basename(input_dem))[0] out_int_base = intermediate_folder + os.path.splitext(os.path.basename(input_dem))[0] #List of predictors available that will be filled predictors = [] if mask == True: masked_out = out_int_base + '_Masked.img' if os.path.exists(masked_out) == False: print 'Masking no data values' outCon = Con(input_dem, input_dem, "","VALUE > " + str(no_data)) outCon.save(masked_out) del outCon else: masked_out = input_dem #Fill the dem dem_fill = out_int_base + '_Fill.img' if os.path.exists(dem_fill) == False: print 'Filling DEM', input_dem print outFill = Fill(masked_out) outFill.save(dem_fill) del outFill #Find some basic info about teh filled dem for use in subsequent steps info = gp.Describe(dem_fill) res = info.meanCellHeight #Calculates the hillshade hillshade = out_int_base + '_hillshade.img' if os.path.exists(hillshade) == False: print 'Calculating the hillshade of', dem_fill print outHillShade = gp.sa.Hillshade(dem_fill, 315, 45, "SHADOWS", 1) outHillShade.save(hillshade) del outHillShade #Calculate the flow direction dem_flow_dir = out_int_base + '_Flow_Dir.img' if os.path.exists(dem_flow_dir) == False: print 'Calculating DEM flow direction from', dem_fill print outFlowDir = FlowDirection(dem_fill) outFlowDir.save(dem_flow_dir) del outFlowDir #Calculate the flow accumulation area in square units (assumed to be meters) dem_flow_acc = out_int_base + '_Flow_Accumulation_sq_m.img' if os.path.exists(dem_flow_acc) == False: print 'Calculating DEM flow accumulation from', dem_flow_dir print outFlowAcc = FlowAccumulation(dem_flow_dir) * res * res outFlowAcc.save(dem_flow_acc) del outFlowAcc #Creates the drainage network by thresholding the flow accumulation layer dem_drainage_network = out_int_base + '_Drainage_Network.img' if os.path.exists(dem_drainage_network) == False: print 'Thresholding the DEM drainage network from', dem_flow_acc print outCon2 = Con(dem_flow_acc, "1", "", "VALUE > " + str(flow_initiation_threshold)) outCon2.save(dem_drainage_network) del outCon2 #Converts the raster drainage network to a vector (this is never used in the actual model) dem_drainage_network_shp = out_int_base + '_Drainage_Network_s.shp' if os.path.exists(dem_drainage_network_shp) == False: print 'Converting raster DEM drainage network to a shapefile' print outPoly = gp.RasterToPolyline_conversion(dem_drainage_network, dem_drainage_network_shp) del outPoly #Computes the Strahler stream order stream_order = out_int_base + '_Strahler_Stream_Order.img' if os.path.exists(stream_order) == False: print 'Computing the Strahler stream order' print outSO = StreamOrder(dem_drainage_network, dem_flow_dir, "STRAHLER") outSO.save(stream_order) del outSO #Computes the stream links stream_link = out_int_base + '_Stream_Links.img' if os.path.exists(stream_link) == False: print 'Creating stream links' print SL = StreamLink(dem_drainage_network, dem_flow_dir) SL.save(stream_link) del SL #Creates watersheds watersheds = out_int_base + '_Watersheds.img' if os.path.exists(watersheds) == False: print 'Identifying watersheds' print WS = Watershed(dem_flow_dir, stream_link, "VALUE") WS.save(watersheds) del WS #All subsequent variables are predictor variables #Computes the slope in radians (percent/100) and smooths it using a 6x6 circular kernel to reduce artifacts slope_radians = out_base + '_Slope_Radians.img' predictors.append(slope_radians) if os.path.exists(slope_radians) == False: print 'Calculating radian slope from', dem_fill print neighborhood = NbrCircle(3, "CELL") slpRad = Slope(dem_fill, "PERCENT_RISE")/100.0 slpRadSmth = FocalStatistics(slpRad, neighborhood, "MEAN") slpRadSmth.save(slope_radians) del slpRad del slpRadSmth ## #Computes curvature ## curvature = out_base + '_Curvature.img' ## plan_curve = out_base + '_Plan_Curvature.img' ## profile_curve = out_base + '_Profile_Curvature.img' ## predictors.append(curvature) ## ## if os.path.exists(curvature) == False: ## print 'Calculating curvature' ## print ## curv = Curvature(dem_fill, 1, profile_curve, plan_curve) ## neighborhood = NbrCircle(2, "CELL") ## curvSmth = FocalStatistics(curv, neighborhood, "MEAN") ## curvSmth.save(curvature) #Computes the height above channel (assumed to be in meters) hac = out_base + '_Height_Above_Channel.img' predictors.append(hac) if os.path.exists(hac) == False: print 'Calculating the height above the channel' print outHAC = CostDistance(dem_drainage_network, slope_radians) outHAC.save(hac) del outHAC #Computes teh euclidean distance from the channel euc = out_base + '_Euclidean_Distance_from_Channel.img' predictors.append(euc) if os.path.exists(euc) == False: print 'Calculating the euclidean distance from channel' print outEuc = EucDistance(dem_drainage_network, cell_size = res) outEuc.save(euc) del outEuc #Computes the product of the euclidean distance and slope (slightly different from the height above the channel) eucxslope = out_base + '_Euc_times_Slope.img' predictors.append(eucxslope) if os.path.exists(eucxslope) == False: print 'Multplying the euclidean distance by the slope' print outEucxSlope = Times(euc, slope_radians) outEucxSlope.save(eucxslope) del outEucxSlope #Computes the topographic position index (TPI) #Difference in elevation between a pixel and the average of its neighborhood #Currently uses a circular kernel of varying diameters #The z suffix indicates that it is the z score of the elevation within a given neighborhood tpis = [20,30,40, 60] for tpi in tpis: tpi_out = out_base + '_TPI_'+str(tpi)+'.img' tpi_outz = out_base + '_TPI_'+str(tpi)+'z.img' predictors.append(tpi_out) predictors.append(tpi_outz) if os.path.exists(tpi_out) == False or os.path.exists(tpi_outz) == False: neighborhood = NbrCircle(tpi/2, "CELL") print 'Computing the topographic position index neighborhood', tpi print mean = FocalStatistics(dem_fill, neighborhood, "MEAN") std = FocalStatistics(dem_fill, neighborhood, "STD") tpir = dem_fill - mean tpir.save(tpi_out) del tpir tpizr = (dem_fill - mean)/std tpizr.save(tpi_outz) del mean del std del tpizr #Computes the compound topographic wetness index (CTWI) and smooths it using a 14x14 circular kernel ctwi = out_base + '_CTWI.img' predictors.append(ctwi) if os.path.exists(ctwi) == False: print 'Computing the compound topographic wetness index' print acc = Raster(dem_flow_acc) slp = Raster(slope_radians) neighborhood = NbrCircle(7, "CELL") ctwi_out = FocalStatistics(Ln((acc + 1) * 100 / Tan((slp) + 0.001)), neighborhood, "MEAN") ctwi_out.save(ctwi) del acc del slp del ctwi_out print print print 'The predictors are:' for predictor in predictors: print os.path.basename(predictor) print print print 'Valley bottom prep is complete' return predictors
# Rotate grid lines based on a pivot point - using the input fc centroid # Also requires us to convert to raster, rotate, and then convert back to vector # (As there is no built in vector rotation tool ...) # arcpy.AddMessage('>> Now running rotation process...') arcpy.AddMessage('\n') pivot_point = '{0} {1}'.format(bdy_fc_centroid[0], bdy_fc_centroid[1]) # X Y out_raster = os.path.join(tmp_gdb, bdy_name + '_raster') out_raster_rotated = os.path.join(tmp_gdb, bdy_name + '_raster_r') tmp_fishnet_rotated = os.path.join(tmp_gdb, bdy_name + '_fishnet_r') # Convert to raster, rotate, and convert back to polyline (use 10m to keep our raster cells separate) arcpy.PolylineToRaster_conversion(tmp_fishnet_path, 'OID', out_raster, 'MAXIMUM_LENGTH', 'NONE', 10) arcpy.Rotate_management(out_raster, out_raster_rotated, rotation_val, pivot_point, 'NEAREST') arcpy.RasterToPolyline_conversion(out_raster_rotated, tmp_fishnet_rotated, 'ZERO', 0, 'SIMPLIFY') arcpy.AddMessage( 'Rotated data by specified value: {0} degrees'.format(rotation_val)) # Perform a real simplification on the layer - to tidy up the lines tmp_fishnet_rotated_simpl = tmp_fishnet_rotated + '_s' arcpy.SimplifyLine_cartography(tmp_fishnet_rotated, tmp_fishnet_rotated_simpl, 'POINT_REMOVE', 10) time.sleep(5) arcpy.AddMessage('Simplified/cleaned up data') arcpy.AddMessage('\n') # Clip rotated lines to input boundary # tmp_fishnet_clip = os.path.join(tmp_gdb, bdy_name + '_fishnet_r_s_c') arcpy.Clip_analysis(tmp_fishnet_rotated_simpl, bdy_fc_path, tmp_fishnet_clip) arcpy.AddMessage('>> Clipped new trap lines to input boundary')
def StreamNetwork(output_workspace, contrib_area, threshold, processes): # Check out the ArcGIS Spatial Analyst extension license arcpy.CheckOutExtension("Spatial") # Set environment variables arcpy.env.overwriteOutput = True arcpy.env.workspace = output_workspace # List parameter values arcpy.AddMessage("Workspace: {}".format(arcpy.env.workspace)) arcpy.AddMessage("Contributing Area: " "{}".format(arcpy.Describe(contrib_area).baseName)) arcpy.AddMessage("Threshold: {}".format(str(threshold))) arcpy.AddMessage("Processes: {}".format(str(processes))) # Convert the GDB contrib_area raster to .tif _____________________________ # TauDEM needs an uncompressed raster. Create in GDB because CopyRaster # cannot control compression when exporting to .tif arcpy.env.compression = "NONE" contrib_area_nocompression = os.path.join( output_workspace, os.path.basename(contrib_area) + "_nocompression") arcpy.CopyRaster_management(in_raster=contrib_area, out_rasterdataset=contrib_area_nocompression) arcpy.AddMessage("Uncompressed contrib_area created") contrib_area_tif = os.path.join(os.path.dirname(output_workspace), "contrib_area.tif") arcpy.CopyRaster_management(in_raster=contrib_area_nocompression, out_rasterdataset=contrib_area_tif) arcpy.AddMessage("Uncompressed contrib_area_tif created") # TauDEM Stream definition by threshold - Threshold _______________________ # output thresholded stream raster stream_grid = os.path.join(os.path.dirname(output_workspace), "stream_grid.tif") # Construct command cmd = 'mpiexec -n ' + str( processes ) + ' Threshold -ssa ' + '"' + contrib_area_tif + '"' + ' -src ' + '"' + stream_grid + '"' + ' -thresh ' + str( threshold) arcpy.AddMessage("\nTauDEM command: " + cmd) # Submit command to operating system os.system(cmd) # Capture contents of shell and print it to the arcgis dialog box process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) arcpy.AddMessage('\nProcess started:\n') for line in process.stdout.readlines(): arcpy.AddMessage(line) # Thin stream network - arcpy.sa.Thin _____________________________________ stream_thin = arcpy.sa.Thin(in_raster=stream_grid, corners="SHARP") stream_thin_path = os.path.join(os.path.dirname(output_workspace), "stream_thin.tif") arcpy.CopyRaster_management(in_raster=stream_thin, out_rasterdataset=stream_thin_path) # Convert raster stream to polyline _______________________________________ # output vector stream network stream_network = os.path.join(output_workspace, "stream_network") # Convert the `stream_thin` raster to a polyline arcpy.RasterToPolyline_conversion(in_raster=stream_thin_path, out_polyline_features=stream_network) arcpy.AddMessage("Stream network created") # Add the `ReachName` field # Check if the field already exists and if not add it field_names = [f.name for f in arcpy.ListFields(stream_network)] if "ReachName" not in field_names: arcpy.AddField_management(in_table=stream_network, field_name="ReachName", field_type="TEXT") # Return arcpy.SetParameter(4, stream_network) # Cleanup arcpy.Delete_management(in_data=contrib_area_nocompression) arcpy.Delete_management(in_data=contrib_area_tif) arcpy.Delete_management(in_data=stream_grid) arcpy.Delete_management(in_data=stream_thin_path) arcpy.AddMessage("Temp datasets deleted")
mosaicFlowGrid = arcpy.MosaicToNewRaster_management([dem, detailed], workingDirectory, "flowMosaic", detailed, "8_BIT_SIGNED", 30, 1, "MAXIMUM", "FIRST") else: mosaicFlowGrid = workingDirectory + "/flowMosaic" # Convert the mosaicked flow grid to a polyline so the points can be snapped to it if not arcpy.Exists(workingDirectory + "/vectorMosaic"): mosaicFlowLines = arcpy.RasterToPolyline_conversion(mosaicFlowGrid, workingDirectory + "/vectorMosaic", "NODATA", "", "NO_SIMPLIFY") else: mosaicFlowLines = workingDirectory + "/vectorMosaic" # ========================== # Observed points processing # ========================== # Make a feature layer of the observed points so it can be processed arcpy.MakeFeatureLayer_management(observed, "pointsLyr") # Snap the points to the flowlines arcpy.Snap_edit("pointsLyr", [[mosaicFlowLines, "EDGE", bufferInMeters + " Meters"]]) # Sample the different versions of flow grids so the points can be classified. The points now lie on these grids after snapping
def FlowPath(in_dem, in_sink, rain_intensity, out_flowpath): arcpy.CheckOutExtension("Spatial") workspace = os.path.split(out_flowpath)[0] arcpy.env.workspace = workspace arcpy.env.overwriteOutput = True dem = arcpy.Raster(in_dem) cell_size = dem.meanCellWidth if arcpy.Exists(in_dem) == False: arcpy.AddMessage("The input raster does not exist") quit() if os.path.splitext(out_flowpath)[1].lower() == ".shp": FieldOID = "FID" FlowDir = os.path.join(workspace, "FlowDir.tif") SinkCentroid = os.path.join(workspace, "SinkCentroid.shp") CostPath = os.path.join(workspace, "CostPath.tif") PathThin = os.path.join(workspace, "PathThin.tif") PathLine = os.path.join(workspace, "PathLine.shp") PathLineErase = os.path.join(workspace, "PathLineErase.shp") Path = os.path.join(workspace, "FlowPath_Raw.shp") # Path = out_flowpath LineFlip = os.path.join(workspace, "LineFlip.shp") LineNoFlip = os.path.join(workspace, "LineNoFlip.shp") FlowFrom = os.path.join(workspace, "FlowFrom.shp") FlowTo = os.path.join(workspace, "FlowTo.shp") PathLineEraseSingle = os.path.join(workspace, "PathLineEraseSingle.shp") LineStart = os.path.join(workspace, "LineStart.shp") LineEnd = os.path.join(workspace, "LineEnd.shp") LineStartElev = os.path.join(workspace, "LineStartElev.shp") LineEndElev = os.path.join(workspace, "LineEndElev.shp") PathBuffer = os.path.join(workspace, "PathBuffer.shp") PathBufferSingle = os.path.join(workspace, "PathBufferSingle.shp") FlowFromJoin = os.path.join(workspace, "FlowFromJoin.shp") FlowToJoin = os.path.join(workspace, "FlowToJoin.shp") FlowFromJoinBuffer = os.path.join(workspace, "FlowFromJoinBuffer.shp") FlowToJoinBuffer = os.path.join(workspace, "FlowToJoinBuffer.shp") else: FieldOID = "OBJECTID" FlowDir = os.path.join(workspace, "FlowDir") SinkCentroid = os.path.join(workspace, "SinkCentroid") CostPath = os.path.join(workspace, "CostPath") PathThin = os.path.join(workspace, "PathThin") PathLine = os.path.join(workspace, "PathLine") PathLineErase = os.path.join(workspace, "PathLineErase") Path = os.path.join(workspace, "FlowPath") LineFlip = os.path.join(workspace, "LineFlip") LineNoFlip = os.path.join(workspace, "LineNoFlip") FlowFrom = os.path.join(workspace, "FlowFrom") FlowTo = os.path.join(workspace, "FlowTo") LineStart = os.path.join(workspace, "LineStart.shp") LineEnd = os.path.join(workspace, "LineEnd.shp") ### Delineate flow direction flow_dir = arcpy.sa.FlowDirection(in_dem) flow_dir.save(FlowDir) ### Extract the depression polygon centroids arcpy.FeatureToPoint_management(in_sink, SinkCentroid, "INSIDE") ### Delineate cost path cost_path = arcpy.sa.CostPath(SinkCentroid, in_dem, FlowDir, "EACH_CELL", FieldOID) cost_path.save(CostPath) ### Thin the raster cost path to single-cell width path_thin = arcpy.sa.Thin(cost_path, "#", "#", "#", 1) path_thin.save(PathThin) ### Convert the raster path to vector arcpy.RasterToPolyline_conversion(path_thin, PathLine, simplify="NO_SIMPLIFY") ### Erase the flow path within depression polygons arcpy.Erase_analysis(PathLine, in_sink, PathLineErase) arcpy.MultipartToSinglepart_management(PathLineErase, PathLineEraseSingle) arcpy.FeatureVerticesToPoints_management(PathLineEraseSingle, LineStart, "START") arcpy.FeatureVerticesToPoints_management(PathLineEraseSingle, LineEnd, "END") arcpy.sa.ExtractValuesToPoints(LineStart, in_dem, LineStartElev) arcpy.sa.ExtractValuesToPoints(LineEnd, in_dem, LineEndElev) arcpy.AddField_management(LineStartElev, field_name="FromElev", field_type="FLOAT") arcpy.AddField_management(LineEndElev, field_name="ToElev", field_type="FLOAT") arcpy.CalculateField_management( in_table=LineStartElev, field="FromElev", expression="!RASTERVALU!", expression_type="PYTHON", code_block="", ) arcpy.CalculateField_management( in_table=LineEndElev, field="ToElev", expression="!RASTERVALU!", expression_type="PYTHON", code_block="", ) arcpy.JoinField_management( in_data=PathLineEraseSingle, in_field="FID", join_table=LineStartElev, join_field="FID", fields="FromElev", ) arcpy.JoinField_management( in_data=PathLineEraseSingle, in_field="FID", join_table=LineEndElev, join_field="FID", fields="ToElev", ) arcpy.CopyFeatures_management(PathLineEraseSingle, Path) # ExtractElevation(PathLineErase, in_dem, Path) arcpy.AddField_management(Path, "Flip", "SHORT") FromElev = arcpy.AddFieldDelimiters(workspace, "FromElev") ToElev = arcpy.AddFieldDelimiters(workspace, "ToElev") sql = FromElev + "<" + ToElev sql2 = FromElev + ">=" + ToElev arcpy.Select_analysis(Path, LineFlip, sql) arcpy.CalculateField_management(LineFlip, "Flip", "1", "PYTHON") arcpy.FlipLine_edit(LineFlip) arcpy.Select_analysis(Path, LineNoFlip, sql2) arcpy.Delete_management(Path) MergeList = [] MergeList.append(LineFlip) MergeList.append(LineNoFlip) arcpy.Merge_management(MergeList, Path) arcpy.AddField_management(Path, field_name="StartElev", field_type="FLOAT") arcpy.AddField_management(Path, field_name="EndElev", field_type="FLOAT") arcpy.AddField_management(Path, field_name="DiffElev", field_type="FLOAT") arcpy.AddField_management(Path, field_name="Length", field_type="FLOAT") arcpy.CalculateField_management( in_table=Path, field="StartElev", expression="max( !FromElev! , !ToElev! )", expression_type="PYTHON", code_block="", ) arcpy.CalculateField_management( in_table=Path, field="EndElev", expression="min( !FromElev! , !ToElev! )", expression_type="PYTHON", code_block="", ) arcpy.CalculateField_management( in_table=Path, field="DiffElev", expression="!StartElev! - !EndElev!", expression_type="PYTHON", code_block="", ) arcpy.CalculateField_management( Path, "Length", "!shape.length@meters!", "PYTHON_9.3", "#" ) arcpy.DeleteField_management( in_table=Path, drop_field="ARCID;GRID_CODE;FROM_NODE;TO_NODE;ORIG_FID;FromElev;ToElev;Flip", ) sql3 = "Length >" + str( 2 * cell_size ) # if flow path is shorter than 2 pixels, delete arcpy.Select_analysis(Path, out_flowpath, sql3) arcpy.FeatureVerticesToPoints_management(out_flowpath, FlowFrom, "START") arcpy.FeatureVerticesToPoints_management(out_flowpath, FlowTo, "END") arcpy.AddField_management(FlowFrom, field_name="FlowFromID", field_type="Long") arcpy.AddField_management(FlowTo, field_name="FlowToID", field_type="Long") arcpy.CalculateField_management( in_table=FlowFrom, field="FlowFromID", expression="!FID! + 1", expression_type="PYTHON", code_block="", ) arcpy.CalculateField_management( in_table=FlowTo, field="FlowToID", expression="!FID! + 1", expression_type="PYTHON", code_block="", ) # derive sink connectivity arcpy.Buffer_analysis( in_features=Path, out_feature_class=PathBuffer, buffer_distance_or_field="0.1 Meters", line_side="FULL", line_end_type="FLAT", dissolve_option="ALL", dissolve_field="", method="PLANAR", ) arcpy.MultipartToSinglepart_management( in_features=PathBuffer, out_feature_class=PathBufferSingle ) arcpy.AddField_management( PathBufferSingle, field_name="BufferID", field_type="Long" ) arcpy.CalculateField_management( in_table=PathBufferSingle, field="BufferID", expression="!FID! + 1", expression_type="PYTHON", code_block="", ) search_radius = str(2.1 * cell_size) + " Meters" arcpy.SpatialJoin_analysis( target_features=FlowFrom, join_features=in_sink, out_feature_class=FlowFromJoin, join_operation="JOIN_ONE_TO_ONE", join_type="KEEP_COMMON", # field_mapping="""ID "ID" true true false 10 Long 0 10 ,First,#,poly,ID,-1,-1""", match_option="INTERSECT", search_radius=search_radius, distance_field_name="", ) arcpy.SpatialJoin_analysis( target_features=FlowTo, join_features=in_sink, out_feature_class=FlowToJoin, join_operation="JOIN_ONE_TO_ONE", join_type="KEEP_COMMON", # field_mapping="""ID "ID" true true false 10 Long 0 10 ,First,#,poly,ID,-1,-1""", match_option="INTERSECT", search_radius=search_radius, distance_field_name="", ) arcpy.SpatialJoin_analysis( target_features=FlowFromJoin, join_features=PathBufferSingle, out_feature_class=FlowFromJoinBuffer, join_operation="JOIN_ONE_TO_ONE", join_type="KEEP_COMMON", # field_mapping="""ID "ID" true true false 10 Long 0 10 ,First,#,poly,ID,-1,-1""", match_option="INTERSECT", search_radius=search_radius, distance_field_name="", ) arcpy.SpatialJoin_analysis( target_features=FlowToJoin, join_features=PathBufferSingle, out_feature_class=FlowToJoinBuffer, join_operation="JOIN_ONE_TO_ONE", join_type="KEEP_COMMON", # field_mapping="""ID "ID" true true false 10 Long 0 10 ,First,#,poly,ID,-1,-1""", match_option="INTERSECT", search_radius=search_radius, distance_field_name="", ) arcpy.JoinField_management( in_data=FlowFromJoinBuffer, in_field="BufferID", join_table=FlowToJoinBuffer, join_field="BufferID", fields="ID", ) arcpy.JoinField_management( in_data=in_sink, in_field="ID", join_table=FlowFromJoinBuffer, join_field="ID", fields="ID_12", ) arcpy.AddField_management(in_sink, field_name="Downstream", field_type="LONG") arcpy.CalculateField_management( in_table=in_sink, field="Downstream", expression="!ID_12!", expression_type="PYTHON", code_block="", ) arcpy.DeleteField_management(in_table=in_sink, drop_field="ID_12") arcpy.AddField_management(in_sink, field_name="simu_depth", field_type="FLOAT") arcpy.AddField_management(in_sink, field_name="rain_inten", field_type="FLOAT") arcpy.AddField_management(in_sink, field_name="time_inund", field_type="FLOAT") arcpy.CalculateField_management( in_table=in_sink, field="simu_depth", expression="!volume! / !cat_area!", expression_type="PYTHON", code_block="", ) arcpy.CalculateField_management( in_table=in_sink, field="rain_inten", expression=rain_intensity, expression_type="PYTHON", code_block="", ) arcpy.CalculateField_management( in_table=in_sink, field="time_inund", expression="!simu_depth! / !rain_inten!", expression_type="PYTHON", code_block="", ) arcpy.JoinField_management( in_data=out_flowpath, in_field="FID", join_table=FlowFromJoin, join_field="ORIG_FID", fields="ID", ) arcpy.AddField_management( in_table=out_flowpath, field_name="start_sink", field_type="LONG" ) arcpy.CalculateField_management( in_table=out_flowpath, field="start_sink", expression="!ID!", expression_type="PYTHON", code_block="", ) arcpy.DeleteField_management(in_table=out_flowpath, drop_field="ID") arcpy.JoinField_management( in_data=out_flowpath, in_field="FID", join_table=FlowToJoin, join_field="ORIG_FID", fields="ID", ) arcpy.AddField_management( in_table=out_flowpath, field_name="end_sink", field_type="LONG" ) arcpy.CalculateField_management( in_table=out_flowpath, field="end_sink", expression="!ID!", expression_type="PYTHON", code_block="", ) arcpy.DeleteField_management(in_table=out_flowpath, drop_field="ID") arcpy.JoinField_management( in_data=out_flowpath, in_field="start_sink", join_table=in_sink, join_field="ID", fields="volume;cat_area;simu_depth;rain_inten;time_inund", ) arcpy.Delete_management(LineFlip) arcpy.Delete_management(LineNoFlip) arcpy.Delete_management(CostPath) arcpy.Delete_management(FlowDir) arcpy.Delete_management(PathLineErase) arcpy.Delete_management(PathThin) arcpy.Delete_management(LineStart) arcpy.Delete_management(LineStartElev) arcpy.Delete_management(LineEnd) arcpy.Delete_management(LineEndElev) arcpy.Delete_management(PathLineEraseSingle) arcpy.Delete_management(SinkCentroid) arcpy.Delete_management(PathLine) arcpy.Delete_management(PathBuffer) arcpy.Delete_management(PathBufferSingle) arcpy.Delete_management(FlowFromJoin) arcpy.Delete_management(FlowToJoin) arcpy.Delete_management(FlowFromJoinBuffer) arcpy.Delete_management(FlowToJoinBuffer) arcpy.AddMessage("Flow path delineation done!") return out_flowpath
import arcpy, os, sys from arcpy import env from arcpy.sa import * #set the workspace and list all of the raster dataset #env.workspace=r'D:\Analysis\Greenland_Analysis\GreenlandHighRes\StreamExtraction\multioutput\watermask\toprocess' env.workspace = r'F:\Courtney\Greenland_Code\Courtney_Stream_Extraction\multioutput\watermask' #r'D:\2012Images\WorldView\geotiff\730\resample\watermask' env.overwriteOutput = True #output=r'D:\Analysis\Greenland_Analysis\GreenlandHighRes\StreamExtraction\multioutput\watermask\toprocess\output' img_output = r'F:\Courtney\Greenland_Code\Courtney_Stream_Extraction\multioutput\thinned_img' shp_output = r'F:\Courtney\Greenland_Code\Courtney_Stream_Extraction\multioutput\thinned_shapefile' #r'D:\2012Images\WorldView\geotiff\730\resample\watermask\output' arcpy.CheckOutExtension("Spatial") tiffs = arcpy.ListRasters("*", "img") print tiffs arcpy.CheckOutExtension("Spatial") for tiff in tiffs: print "start process " + tiff outThinnedRaster = img_output + "\\" + (tiff.split('.'))[0] + "thin.img" outFeatureClass = shp_output + "\\" + (tiff.split('.'))[0] + ".shp" thinOut = Thin(tiff, "ZERO", "NO_FILTER", "ROUND") thinOut.save(outThinnedRaster) arcpy.RasterToPolyline_conversion(outThinnedRaster, outFeatureClass, "ZERO", 50, "NO_SIMPLIFY", "")
# - Write out edges to an edge list; setting to VALUE > patchID writes only the lower half of the matrix recs = arcpy.SearchCursor(zStatTable,"VALUE > %d" %patchID) rec = recs.next() while rec: outFile.write("%d,%d,%s\n" %(patchID, rec.VALUE, rec.MIN)) # - If asked to write LCPs, here we go if computeLCPs == 'true': ToPatchID = rec.VALUE if rec.MIN > 0: # Isolate the to-patch ToPatch = sa.SetNull(patchRaster,patchRaster,"VALUE <> %d" %ToPatchID) # Calculate the least cost path to the to_patch lcpRaster = sa.CostPath(ToPatch,costDist,backLink,"BEST_SINGLE") # Convert the raster to a feature lcpFeature = "in_memory/LCPfeature" result = arcpy.RasterToPolyline_conversion(lcpRaster,lcpFeature) # Dissolve the feature lcpDissolve = "in_memory/LCPdissolve" result = arcpy.Dissolve_management(lcpFeature,lcpDissolve) # Copy the features over to the LCP feature class cur = arcpy.InsertCursor(lcpFC) feat = cur.newRow() feat.shape = arcpy.SearchCursor(lcpDissolve).next().shape feat.FromID = patchID feat.ToID = ToPatchID feat.Cost = rec.MIN cur.insertRow(feat) del feat, cur rec = recs.next() del rec, recs
def get_centerline (feature, dem, workspace, power = 5, eu_cell_size = 10): """Returns a center line feature of the given polygon feature based on cost over an euclidean distance raster and cost path. points are seeded using minimum and maximum elevation.""" centerline = workspace + '\\centerline.shp' center_length = 0 center_slope = 0 smoothing = 4 trim_distance = "100 Meters" try: # Setup extents / environments for the current feature ARCPY.env.extent = feature.shape.extent XMin_new = ARCPY.env.extent.XMin - 200 YMin_new = ARCPY.env.extent.YMin - 200 XMax_new = ARCPY.env.extent.XMax + 200 YMax_new = ARCPY.env.extent.YMax + 200 ARCPY.env.extent = ARCPY.arcpy.Extent(XMin_new, YMin_new, XMax_new, YMax_new) ARCPY.env.overwriteOutput = True ARCPY.env.cellSize = eu_cell_size ARCPY.env.snapRaster = dem # Get minimum and maximum points resample = ARCPY.Resample_management (dem, 'in_memory\\sample', eu_cell_size) masked_dem = ARCPY.sa.ExtractByMask (resample, feature.shape) # Find the maximum elevation value in the feature, convert them to # points and then remove all but one. maximum = get_properties (masked_dem, 'MAXIMUM') maximum_raster = ARCPY.sa.SetNull(masked_dem, masked_dem, 'VALUE <> ' + maximum) maximum_point = ARCPY.RasterToPoint_conversion(maximum_raster, 'in_memory\\max_point') rows = ARCPY.UpdateCursor (maximum_point) for row in rows: if row.pointid <> 1: rows.deleteRow(row) del row, rows # Find the minimum elevation value in the feature, convert them to # points and then remove all but one. minimum = get_properties (masked_dem, 'MINIMUM') minimum_raster = ARCPY.sa.SetNull(masked_dem, masked_dem, 'VALUE <> ' + minimum) minimum_point = ARCPY.RasterToPoint_conversion(minimum_raster, 'in_memory\\min_point') rows = ARCPY.UpdateCursor (minimum_point) for row in rows: if row.pointid <> 1: rows.deleteRow(row) del row, rows # Calculate euclidean Distance to boundary line for input DEM cells. polyline = ARCPY.PolygonToLine_management(feature.shape, 'in_memory\\polyline') eucdist = ARCPY.sa.EucDistance(polyline, "", eu_cell_size, '') masked_eucdist = ARCPY.sa.ExtractByMask (eucdist, feature.shape) # Calculate the cost raster by inverting the euclidean distance results, # and raising it to the power of x to exaggerate the least expensive route. cost_raster = (-1 * masked_eucdist + float(maximum))**power # Run the cost distance and cost path function to find the path of least # resistance between the minimum and maximum values. The results are set # so all values equal 1 (different path segments have different values) # and convert the raster line to a poly-line. backlink = 'in_memory\\backlink' cost_distance = ARCPY.sa.CostDistance(minimum_point, cost_raster, '', backlink) cost_path = ARCPY.sa.CostPath(maximum_point, cost_distance, backlink, 'EACH_CELL', '') cost_path_ones = ARCPY.sa.Con(cost_path, 1, '', 'VALUE > ' + str(-1)) # Set all resulting pixels to 1 r_to_p = ARCPY.RasterToPolyline_conversion (cost_path_ones, 'in_memory\\raster_to_polygon') del ARCPY.env.extent # Delete current extents (need here but do not know why) # Removes small line segments from the centerline shape. These segments are # a byproduct of cost analysis. lines = str(ARCPY.GetCount_management(r_to_p)) #check whether we have more than one line segment if float(lines) > 1: # If there is more then one line rows = ARCPY.UpdateCursor(r_to_p) for row in rows: if row.shape.length == eu_cell_size: # delete all the short 10 m lines rows.deleteRow(row) del row, rows lines = str(ARCPY.GetCount_management(r_to_p)) if float(lines) > 1: ARCPY.Snap_edit(r_to_p, [[r_to_p, "END", "50 Meters"]]) # make sure that the ends of the lines are connected r_to_p = ARCPY.Dissolve_management(r_to_p, 'in_memory\\raster_to_polygon_dissolve') # Smooth the resulting line. Currently smoothing is determined by minimum # and maximum distance. The greater change the greater the smoothing. smooth_tolerance = (float(maximum) - float(minimum)) / smoothing ARCPY.SmoothLine_cartography(r_to_p, centerline, 'PAEK', smooth_tolerance, 'FIXED_CLOSED_ENDPOINT', 'NO_CHECK') field_names = [] # List of field names in the file that will be deleted. fields_list = ARCPY.ListFields(centerline) for field in fields_list: # Loop through the field names if not field.required: # If they are not required append them to the list of field names. field_names.append(field.name) # Add new fields to the center line feature ARCPY.AddField_management(centerline, 'GLIMSID', 'TEXT', '', '', '25') ARCPY.AddField_management(centerline, 'LENGTH', 'FLOAT') ARCPY.AddField_management(centerline, 'SLOPE', 'FLOAT') ARCPY.DeleteField_management(centerline, field_names) # Remove the old fields. # Calculate the length of the line segment and populate segment data. ARCPY.CalculateField_management(centerline, 'LENGTH', 'float(!shape.length@meters!)', 'PYTHON') rows = ARCPY.UpdateCursor (centerline) for row in rows: row.GLIMSID = feature.GLIMSID # Get GLIMS ID and add it to segment center_length = row.LENGTH # Get the length of the center line # Calculate slope of the line based on change in elevation over length of line center_slope = round(math.degrees(math.atan((float(maximum) - float(minimum)) / row.LENGTH)), 2) row.SLOPE = center_slope # Write slope to Segment rows.updateRow(row) # Update the new entry del row, rows #Delete cursors and remove locks # Flip Line if needed - Turn min point and end point into a line segment if # the length of this line is greater then the threshold set, flip the line. end_point = ARCPY.FeatureVerticesToPoints_management(centerline, 'in_memory\\end_point', 'END') merged_points = ARCPY.Merge_management ([end_point, minimum_point], 'in_memory\\merged_points') merged_line = ARCPY.PointsToLine_management (merged_points, 'in_memory\\merged_line') merged_line_length = 0 # Get the line Length rows = ARCPY.SearchCursor (merged_line) for row in rows: merged_line_length += row.shape.length del row, rows # if the line length is greater then a quarter the entire feature length, flip if merged_line_length > (center_length/4): ARCPY.FlipLine_edit(centerline) # This function attempts to extend the line and clip it back to the # feature extents in order to create a line that runs from edge to edge #trimmed_line = ARCPY.Merge_management([polyline, centerline], 'in_memory\\line_merge') trimmed_line = ARCPY.Append_management (polyline, centerline, 'NO_TEST') ARCPY.TrimLine_edit (trimmed_line, trim_distance, "DELETE_SHORT") ARCPY.ExtendLine_edit(trimmed_line, trim_distance, "EXTENSION") rows = ARCPY.UpdateCursor (trimmed_line) for row in rows: if row.LENGTH == 0.0: rows.deleteRow(row) del row, rows # Recalculate length. Must be after 0.0 lengths are deleted or they will # not be removed above. ARCPY.CalculateField_management(centerline, 'LENGTH', 'float(!shape.length@meters!)', 'PYTHON') ARCPY.env.overwriteOutput = False return centerline, center_length, center_slope, False except: ARCPY.env.overwriteOutput = False return centerline, '', '', True
def execute_FlowLength(r_flowdir, str_frompoint, str_result, riverline, messages, language="FR"): """The source code of the tool.""" flowdir = RasterIO(r_flowdir) Result = RasterIO(r_flowdir, str_result, float, -255) frompointcursor = arcpy.da.SearchCursor(str_frompoint, "SHAPE@") for frompoint in frompointcursor: frompointshape = frompoint[0].firstPoint # Conversion des coordonnées currentcol = flowdir.XtoCol(frompointshape.X) currentrow = flowdir.YtoRow(frompointshape.Y) intheraster = True if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height: intheraster = False elif (flowdir.getValue(currentrow, currentcol) != 1 and flowdir.getValue(currentrow, currentcol) != 2 and flowdir.getValue(currentrow, currentcol) != 4 and flowdir.getValue(currentrow, currentcol) != 8 and flowdir.getValue(currentrow, currentcol) != 16 and flowdir.getValue(currentrow, currentcol) != 32 and flowdir.getValue(currentrow, currentcol) != 64 and flowdir.getValue(currentrow, currentcol) != 128): intheraster = False totaldistance = 0 currentdistance = 0 while (intheraster): totaldistance = totaldistance + currentdistance Result.setValue(currentrow, currentcol, totaldistance) # looking for the next point direction = flowdir.getValue(currentrow, currentcol) if (direction == 1): currentcol = currentcol + 1 currentdistance = flowdir.raster.meanCellWidth if (direction == 2): currentcol = currentcol + 1 currentrow = currentrow + 1 currentdistance = math.sqrt(flowdir.raster.meanCellWidth * flowdir.raster.meanCellWidth + flowdir.raster.meanCellHeight * flowdir.raster.meanCellHeight) if (direction == 4): currentrow = currentrow + 1 currentdistance = flowdir.raster.meanCellHeight if (direction == 8): currentcol = currentcol - 1 currentrow = currentrow + 1 currentdistance = math.sqrt(flowdir.raster.meanCellWidth * flowdir.raster.meanCellWidth + flowdir.raster.meanCellHeight * flowdir.raster.meanCellHeight) if (direction == 16): currentcol = currentcol - 1 currentdistance = flowdir.raster.meanCellWidth if (direction == 32): currentcol = currentcol - 1 currentrow = currentrow - 1 currentdistance = math.sqrt(flowdir.raster.meanCellWidth * flowdir.raster.meanCellWidth + flowdir.raster.meanCellHeight * flowdir.raster.meanCellHeight) if (direction == 64): currentrow = currentrow - 1 currentdistance = flowdir.raster.meanCellHeight if (direction == 128): currentcol = currentcol + 1 currentrow = currentrow - 1 currentdistance = math.sqrt(flowdir.raster.meanCellWidth * flowdir.raster.meanCellWidth + flowdir.raster.meanCellHeight * flowdir.raster.meanCellHeight) if currentcol < 0 or currentcol >= flowdir.raster.width or currentrow < 0 or currentrow >= flowdir.raster.height: intheraster = False elif (flowdir.getValue(currentrow, currentcol) != 1 and flowdir.getValue(currentrow, currentcol) != 2 and flowdir.getValue(currentrow, currentcol) != 4 and flowdir.getValue(currentrow, currentcol) != 8 and flowdir.getValue(currentrow, currentcol) != 16 and flowdir.getValue(currentrow, currentcol) != 32 and flowdir.getValue(currentrow, currentcol) != 64 and flowdir.getValue(currentrow, currentcol) != 128): intheraster = False if intheraster: if (Result.getValue(currentrow, currentcol) != Result.nodata): # Atteinte d'une confluence intheraster = False Result.save() if riverline is not None: r_rivers = arcpy.sa.SetNull(arcpy.sa.IsNull(Result.raster), 1, "VALUE = 1") arcpy.RasterToPolyline_conversion(r_rivers, riverline) return
def convert(costpath, file_name_1, file_name_2, name_1, name_2): try: arcpy.RasterToPolyline_conversion( costpath, directory + '\polylines\pl_' + file_name_1 + '_' + file_name_2, "ZERO", 10, "SIMPLIFY") distance = 0 with arcpy.da.SearchCursor( directory + '\polylines\pl_' + file_name_1 + '_' + file_name_2 + '.shp', ['SHAPE@LENGTH']) as poly_cursor: for row in poly_cursor: distance += row[0] # sum distance for each polyline segment except arcpy.ExecuteError: error = arcpy.GetMessages(2) str_error = str(error) if str_error.startswith('ERROR 010151'): print( '\nCannot convert cost path raster between ' + loc_one_name + ' and ' + loc_two_name + ' to a valid polyline, but rest of data should be saved properly. Source and destination may be too' 'close to each other.') print( 'Linear distance between source and destination set to zero in output table.' ) print(str(error)) log.write( asctime() + ': Cannot convert cost path raster between ' + loc_one_name + ' and ' + loc_two_name + ' to a valid polyline, but rest of data should be saved properly.\n' + 'Linear distance between source and destination set to zero in output table.\n' + str(error) + '------------------------------------------------------------------------------------------' + '\n') distance = 0 else: print( '\nCannot convert cost path raster between ' + loc_one_name + ' and ' + loc_two_name + ' to a valid polyline, but rest of data should be saved properly.' ) print( 'Linear distance between source and destination not calculated.' ) print(str(error)) log.write( asctime() + ': Cannot convert cost path raster between ' + loc_one_name + ' and ' + loc_two_name + ' to a valid polyline, but rest of data should be saved properly.\n' + 'Linear distance between source and destination not calculated.\n' + str(error) + '------------------------------------------------------------------------------------------' + '\n') distance = 'NA' except Exception as error: print('\nCannot convert cost path raster between ' + loc_one_name + ' and ' + loc_two_name + ' to a valid polyline.') print('Linear distance between source and destination not calculated.') print(str(error)) log.write( asctime() + ': Cannot convert cost path raster between ' + loc_one_name + ' and ' + loc_two_name + ' to a valid polyline, but rest of data should be saved properly.\n' + 'Linear distance between source and destination not calculated.\n' + str(error) + '------------------------------------------------------------------------------------------' + '\n') distance = 0 try: arcpy.AddField_management(costpath, 'Source', 'TEXT') arcpy.AddField_management(costpath, 'Dest', 'TEXT') arcpy.AddField_management(costpath, 'Distance', 'FLOAT') arcpy.CalculateField_management(costpath, 'Source', "'" + name_1 + "'") arcpy.CalculateField_management(costpath, 'Dest', "'" + name_2 + "'") arcpy.CalculateField_management(costpath, 'Distance', distance) arcpy.MakeTableView_management(costpath, 'table') with arcpy.da.SearchCursor( 'table', ['SOURCE', 'DEST', 'PATHCOST', 'DISTANCE', 'STARTROW' ]) as table_cursor: for entry in table_cursor: if entry[4] != 0: in_cursor = arcpy.da.InsertCursor(table, fields) in_cursor.insertRow( (str(entry[0]), str(entry[1]), entry[2], entry[3])) del in_cursor if int_data is True: try: arcpy.CopyRows_management( costpath, directory + r'\tables\tb_' + file_name_1 + '_' + file_name_2 + '.csv') except Exception as error: print('\nFailed to save data for cost path between ' + loc_one_name + ' and ' + loc_two_name + ' in .csv table. See error message for more details.') print( 'Linear distance between source and destination not calculated.' ) print(str(error)) log.write( asctime() + ': Failed to save data for cost path between ' + loc_one_name + ' and ' + loc_two_name + ' in .csv table. See error message for more details.\n' + str(error) + '------------------------------------------------------------------------------------------' + '\n') try: costpath.save(directory + r'\costpath\cp_' + file_name_1 + '_' + file_name_2) except Exception as error: str_error = str(error) if str_error.startswith('ERROR 010240'): print('\nCould not save cost path raster cp_' + file_name_1 + '_' + file_name_2 + ', but rest of data should be saved properly.') print( 'Combination of file names for fc one and fc two likely exceeds 13 characters. ' 'See help file for more information.') log.write( asctime() + ': Could not save cost path raster cp_' + file_name_1 + '_' + file_name_2 + ', but rest of data should be saved properly.\n' + 'Combination of file names for fc one and fc two likely exceed 13 characters. ' 'See help file for more information.\n' + str(error) + '\n' + '----------------------------------------------------' '--------------------------------------' + '\n') else: print( '\nCould not save cost path raster cp_' + file_name_1 + '_' + file_name_2 + ', but rest of data should be saved properly. See error message for more details' ) print(str(error)) log.write( asctime() + ': Could not save cost path raster cp_' + file_name_1 + '_' + file_name_2 + ', but rest of data should be saved properly. See error message for more details.\n' + '-------------------------------------------------------' '-----------------------------------' + '\n') except arcpy.ExecuteError: error = arcpy.GetMessages(2) print('\nFailed to properly save data for least cost path between ' + loc_one_name + ' and ' + loc_two_name + ' in master table. Script will continue with next iteration(1).') print(str(error)) log.write( asctime() + ': Failed to properly save data for least cost path between ' + loc_one_name + ' and ' + loc_two_name + ' in master table. Script continued with next iteration.' + '.\n' + str(error) + '------------------------------------------------------------------------------------------' + '\n') except Exception as error: print('\nFailed to properly save data for least cost path between ' + loc_one_name + ' and ' + loc_two_name + ' in master table. Script will continue with next iteration(2).') print(str(error)) log.write( asctime() + ': Failed to properly save data for least cost path between ' + loc_one_name + ' and ' + loc_two_name + ' in master table. Script continued with next iteration.' + '.\n' + str(error) + '------------------------------------------------------------------------------------------' + '\n')
Trail_Pour = arcpy.sa.Con(arcpy.sa.Raster("Trail_FlMax") == arcpy.sa.Raster("FlowAcc_DEM"), Trail_Slope) Trail_Pour.save(Trail_Slope_Pt) print ("Trail Pour Points complete.") # Process: TrailPour_Flow - Aspect Trail_Pour = arcpy.sa.Con(arcpy.sa.Raster("Trail_FlMax") == arcpy.sa.Raster("FlowAcc_DEM"), Trail_Aspect) Trail_Pour.save(Trail_Aspect_Pt) print ("Trail Pour Points complete.") # Trail_Relative Slope_Point fiftyPer = arcpy.Raster(Trail_Slope_Pt)/arcpy.Raster(WSF_Slope) fiftyPer.save(Trail_RelSlo_Pt) print ("Trail relative slope complete.") # Process: Trail Polyline - works arcpy.RasterToPolyline_conversion(in_raster=Trail_Seg, out_polyline_features=Trail_Line, background_value="ZERO", minimum_dangle_length="0", simplify="SIMPLIFY", raster_field="Value") print("Trail Segment Polyline complete.") # Process: Trail Bearing arcpy.AddGeometryAttributes_management(Trail_Line, "LINE_BEARING") # Trail_Slope_Alignment_Point TSA_raw = arcpy.Raster(Trail_Aspect_Pt)-arcpy.Raster(WSF_Aspect) TSA_diff = (TSA_raw + 180) % 360 - 180 TSA = arcpy.sa.Abs(TSA_diff) TSA.save(Trail_TSA_Pt) print ("Trail slope alignment complete.") # Trail_TSA _ Fall Line Points TSAover45 = arcpy.sa.Con(arcpy.sa.Raster(Trail_TSA_Pt) < 45, Trail_TSA_Pt) TSAover45.save(TrailTSA_Fall)
def rankPaths(source, pField, curSurface, outConnect, minWidth): arcpy.AddMessage('Generating ranked cost paths for ' + outConnect + '...') cList = [] zList = [] rList = [] ## # Append core areas to connected regions to connect regions that are bisected by source habitat ## ## # Generate Minimum convex hull of connected areas ## arcpy.MinimumBoundingGeometry_management(outConnect, "in_memory\\mcp", "CONVEX_HULL", "ALL") ## arcpy.Clip_analysis(source, "in_memory\\mcp", "in_memory\\src_clp") ## ## #Merge connected and source ## arcpy.Merge_management(["in_memory\\src_clp", outConnect], "in_memory\\connect_merge") ## ## #Dissolve merged connected patches ## arcpy.Dissolve_management("in_memory\\connect_merge", "in_memory\\out_connect_merge", "", "", "SINGLE_PART", "") ## outConnect = "in_memory\\out_connect_merge" # Set intersect tolerance to 3X link layer cell size to prevent Intersect from creating multiple line segments where slivers occur interTol = str(3 * int(arcpy.Describe(link).meanCellWidth)) minWidth = 2 * minWidth cstSurface = arcpy.sa.FocalStatistics(curSurface, arcpy.sa.NbrCircle(minWidth, "Map"), "MEAN", "DATA") # If connected region is not empty, extract cost surface by connected region to limit analysis to connected region if len(connectList) > 0: cstSurface2 = arcpy.CopyRaster_management(cstSurface, "cstSurface2") arcpy.AddMessage('Extracting cost surface by connected area...') cstSurface = arcpy.gp.ExtractByMask_sa(cstSurface, outConnect, "cstSurf") cstSurface = arcpy.Describe(cstSurface).name cstSurface2 = arcpy.Describe(cstSurface2).name # Create line segment where source patches touch connected regions to use as sources for cost paths # Make sure inputs are in same projection sourceProjName = arcpy.Describe(source).spatialreference.name curProjName = arcpy.Describe(cstSurface).spatialreference.name if not sourceProjName == curProjName: arcpy.AddMessage("\tReprojecting source layer...") pSource = arcpy.Project_management( source, os.path.join(arcpy.env.scratchWorkspace, "reproj.shp"), cstSurface) else: pSource = source ## # Add core ares back to current surfaces as zero cost regions ## arcpy.env.cellSize = '"%s"' % arcpy.Describe(cstSurface).catalogPath ## CellSize = str(arcpy.env.cellSize) ## arcpy.PolygonToRaster_conversion(pSource, pField, "in_memory\\rast_source", "", "", CellSize) ## no_null = arcpy.sa.Con(arcpy.sa.IsNull("in_memory\\rast_source"),0,1) ## cstSurface = arcpy.sa.Con(no_null, 0, cstSurface, "VALUE = 1") ## cstSurface2 = arcpy.sa.Con(no_null, 0, cstSurface2, "VALUE = 1") arcpy.AddMessage( '\tIntersecting source patches with connected area to create source regions...' ) pSource = arcpy.EliminatePolygonPart_management(pSource, "in_memory\\eliminate", "PERCENT", "", 10, "CONTAINED_ONLY") try: arcpy.Delete_management( os.path.join(arcpy.env.scratchWorkspace, "reproj.shp")) except: pass pSource = arcpy.Intersect_analysis([[pSource, 1], [outConnect, 1]], "in_memory\\intersect", "ALL", interTol, "LINE") pSource = arcpy.MultipartToSinglepart_management(pSource, "in_memory\\multipart") pSource = arcpy.UnsplitLine_management(pSource, "in_memory\\unsplit", pField) pSource = arcpy.MakeFeatureLayer_management(pSource, "pSource") # Calculate least-cost path for each pair-wise combination of source patches l = getCombinations(source, pField) values = l[0] combs = l[1] # break combination and not connected lists into unique elements and create list of regions with no connections if len(connectList) > 0: theList = connectList else: theList = noConnectList c = list(set(chain.from_iterable(theList))) # Create patch regions and cost distance rasters for each unique value in source patches arcpy.AddMessage( '\tCreating patch regions and cost distance rasters for each unique value in source patches...' ) for v in values: if v in c: v = str(int(v)) arcpy.AddMessage('\t\tProcessing patch region ' + v + '...') arcpy.SelectLayerByAttribute_management(pSource, "NEW_SELECTION", pField + " = " + v) arcpy.MakeFeatureLayer_management(pSource, "p_" + v) cd = arcpy.sa.CostDistance("p_" + v, cstSurface, "", os.path.join(workspace, "bklnk_" + v)) arcpy.MakeRasterLayer_management(cd, "CostDist_" + v) if len(connectList) > 0: rd = arcpy.sa.CostDistance( "p_" + v, cstSurface2, "", os.path.join(workspace, "r_bklnk_" + v)) arcpy.MakeRasterLayer_management(rd, "r_CostDist_" + v) # Create least-cost paths for each region pair in both directions arcpy.AddMessage( '\tGenerating least-cost path for each patch pair combination...') for c in combs: c1 = str(int(c[0])) c2 = str(int(c[1])) if c in theList: arcpy.AddMessage('\t\tCalculating least-cost path from region ' + c1 + ' to region ' + c2 + '...') cp = arcpy.sa.CostPath("p_" + c1, "CostDist_" + c2, "bklnk_" + c2, "BEST_SINGLE", "FID") cp1 = arcpy.MakeRasterLayer_management(cp, "CP_" + c1 + "_" + c2) arcpy.AddMessage('\t\tCalculating least-cost path from region ' + c2 + ' to region ' + c1 + '...') cp = arcpy.sa.CostPath("p_" + c2, "CostDist_" + c1, "bklnk_" + c1, "BEST_SINGLE", "FID") cp2 = arcpy.MakeRasterLayer_management(cp, "CP_" + c2 + "_" + c1) cList.append(str(cp1)) cList.append(str(cp2)) else: arcpy.AddWarning( '\t\tRegions ' + c1 + ' and ' + c2 + ' are not connected. Skipping cost path for this region pair...' ) # Create combined least-cost path polyline layer arcpy.AddMessage('\t\tMosaicing least-cost paths for region pairs...') arcpy.MosaicToNewRaster_management(cList, workspace, "lcp_mos", "", "", "", "1", "MAXIMUM") for c in cList: try: arcpy.Delete_management(c) except: pass arcpy.CalculateStatistics_management(os.path.join(workspace, "lcp_mos")) LCP = arcpy.sa.Con(os.path.join(workspace, "lcp_mos"), "1", "", "VALUE > 0") arcpy.Delete_management(os.path.join(workspace, "lcp_mos")) # Create least-cost paths by zone arcpy.AddMessage( '\tGenerating least-cost paths by zones for each patch pair combination...' ) # Create least-cost paths for each region pair in both directions for c in combs: c1 = str(int(c[0])) c2 = str(int(c[1])) if c in theList: arcpy.AddMessage('\t\tCalculating least-cost path from region ' + c1 + ' to region ' + c2 + '...') zp = arcpy.sa.CostPath("p_" + c1, "CostDist_" + c2, "bklnk_" + c2, "EACH_ZONE", "FID") zp1 = arcpy.MakeRasterLayer_management(zp, "ZP_" + c1 + "_" + c2) arcpy.AddMessage('\t\tCalculating least-cost path from region ' + c2 + ' to region ' + c1 + '...') zp = arcpy.sa.CostPath("p_" + c2, "CostDist_" + c1, "bklnk_" + c1, "EACH_ZONE", "FID") zp2 = arcpy.MakeRasterLayer_management(zp, "ZP_" + c2 + "_" + c1) zList.append(str(zp1)) zList.append(str(zp2)) # Create combined least-cost path polyline layer arcpy.AddMessage('\t\tMosaicing least-cost paths for region zones...') if arcpy.Exists(os.path.join(workspace, "zcp_mos")): arcpy.Delete_management(os.path.join(workspace, "zcp_mos")) arcpy.MosaicToNewRaster_management(zList, workspace, "zcp_mos", "", "", "", "1", "MAXIMUM") for z in zList: try: arcpy.Delete_management(z) except: pass arcpy.CalculateStatistics_management(os.path.join(workspace, "zcp_mos")) ZCP = arcpy.sa.Con(os.path.join(workspace, "zcp_mos"), "2", "", "VALUE > 0") # Create least-cost paths through compromised areas if len(connectList) > 0: # Create patch regions and cost distance rasters for each unique value in source patches arcpy.AddMessage('\tCalculating costs through restoration zones...') arcpy.AddMessage( '\tGenerating potential restoration paths for each patch pair combination...' ) # Create least-cost paths for each region pair in both directions for c in combs: c1 = str(int(c[0])) c2 = str(int(c[1])) if c in theList: arcpy.AddMessage( '\t\tCalculating least-cost path from region ' + c1 + ' to region ' + c2 + '...') rp = arcpy.sa.CostPath("p_" + c1, "r_CostDist_" + c2, "r_bklnk_" + c2, "EACH_ZONE", "FID") rp1 = arcpy.MakeRasterLayer_management(rp, "RP_" + c1 + "_" + c2) arcpy.AddMessage( '\t\tCalculating least-cost path from region ' + c2 + ' to region ' + c1 + '...') rp = arcpy.sa.CostPath("p_" + c2, "r_CostDist_" + c1, "r_bklnk_" + c1, "EACH_ZONE", "FID") rp2 = arcpy.MakeRasterLayer_management(rp, "RP_" + c2 + "_" + c1) rList.append(str(rp1)) rList.append(str(rp2)) # Create combined least-cost path polyline layer arcpy.AddMessage('\t\tMosaicing least-cost paths for region zones...') if arcpy.Exists(os.path.join(workspace, "rcp_mos")): arcpy.Delete_management(os.path.join(workspace, "rcp_mos")) arcpy.MosaicToNewRaster_management(rList, workspace, "rcp_mos", "", "", "", "1", "MAXIMUM") for r in rList: try: arcpy.Delete_management(r) except: pass arcpy.CalculateStatistics_management(os.path.join( workspace, "rcp_mos")) RCP = arcpy.sa.Con(os.path.join(workspace, "rcp_mos"), "3", "", "VALUE > 0") mList = [LCP, ZCP, RCP] else: mList = [LCP, ZCP] arcpy.AddMessage( '\tCombining least-cost paths by region and least-cost paths by region zones...' ) arcpy.MosaicToNewRaster_management(mList, workspace, "lcp_mos", "", "", "", "1", "MINIMUM") LCP = arcpy.RasterToPolyline_conversion(os.path.join(workspace, "lcp_mos"), "LCP", "", "", "NO_SIMPLIFY") # Create a fieldinfo object to rename grid_code field fieldinfo = arcpy.FieldInfo() fieldinfo.addField("GRID_CODE", "PATH_RNK", "VISIBLE", "") outLCP = arcpy.MakeFeatureLayer_management(str(LCP), "outLCP", "", "", fieldinfo) # arcpy.CopyFeatures_management(outLCP, os.path.join(workspace, outLCP.shp)) try: arcpy.Delete_management(os.path.join(workspace, "lcp_mos")) arcpy.Delete_management(os.path.join(workspace, "zcp_mos")) arcpy.Delete_management(os.path.join(workspace, "rcp_mos")) #arcpy.Delete_management("in_memory") except: pass return (outLCP)
try: arcpy.AddMessage("\nFlow direction...") ArcHydroTools.FlowDirection(DEM, flow_dir) arcpy.AddMessage("\nFlow accumulation...") ArcHydroTools.FlowAccumulation(flow_dir, flow_acc) arcpy.AddMessage("\nStream definition...") ArcHydroTools.StreamDefinition(flow_acc, stream_threshold_numcells, streams, "") # Output the streams layer so users can compare with known streams arcpy.CopyRaster_management(streams, streams_out) arcpy.AddMessage("\n\tCreated streams raster file:\n\t" + str(streams_out)) arcpy.RasterToPolyline_conversion(streams_out, streams_out_shp, "NODATA") arcpy.AddMessage("\n\tCreated streams shapefile:\n\t" + str(streams_out_shp)) arcpy.AddMessage("\nStream segmentation...") ArcHydroTools.StreamSegmentation(streams, flow_dir, stream_link, "", "") arcpy.AddMessage("\nCatchment grid delineation...") ArcHydroTools.CatchmentGridDelineation(flow_dir, stream_link, catchment_grid) arcpy.AddMessage("\nCatchment polygons...") ArcHydroTools.CatchmentPolyProcessing(catchment_grid, catchment_poly) arcpy.AddMessage("\nDrainage lines...") ArcHydroTools.DrainageLineProcessing(stream_link, flow_dir, drainage_line) arcpy.AddMessage("\nAdjoint catchments...")
cdRaster = os.path.join(CostDistWS,"CD_%s.img" %to_patch) blRaster = os.path.join(CostDistWS,"BL_%s.img" %to_patch) # Loop through each from patch (skipping ones already processed...) for from_patch in patchIDs: if from_patch <= to_patch: continue msg("Creating least cost path from %s to %s" %(to_patch, from_patch)) # Extract the cost cost = edgeDict[(to_patch,from_patch)] # Isolate the to patch fromPatch = sa.SetNull(patchRaster,patchRaster,"VALUE <> %s" %from_patch) # Calculate least cost paths from all patches to the current patch lcpRaster = sa.CostPath(fromPatch,cdRaster,blRaster,"BEST_SINGLE") # Convert the backlink to a flow direction raster #fdRaster = sa.Int(sa.Exp2(blRaster) / 2) # Convert the LCP raster to a vector arcpy.RasterToPolyline_conversion(lcpRaster,streamFC,'ZERO',0,"NO_SIMPLIFY") #sa.StreamToFeature(lcpRaster,fdRaster,streamFC,"NO_SIMPLIFY") if first: # If the first patch, dissolve to the output FC file arcpy.Dissolve_management(streamFC,lcpFC) arcpy.AddField_management(lcpFC,"FromID","LONG",10) arcpy.AddField_management(lcpFC,"ToID","LONG",10) arcpy.AddField_management(lcpFC,"Cost","DOUBLE",10,2) arcpy.CalculateField_management(lcpFC,"FromID",from_patch) arcpy.CalculateField_management(lcpFC,"ToID",to_patch) arcpy.CalculateField_management(lcpFC,"Cost",cost) first = False else: # Otherwise, dissolve it and append it to the original arcpy.Dissolve_management(streamFC,dslvFC) arcpy.AddField_management(dslvFC,"FromID","LONG",10) arcpy.AddField_management(dslvFC,"ToID","LONG",10) arcpy.AddField_management(dslvFC,"Cost","DOUBLE",10,2)
arcpy.MeanCenter_stats(Input_Feature_Class="min_p", Output_Feature_Class="min_point") print("Get low point") # --- Cost Distance arcpy.gp.CostDistance_sa("max_point", "euc_inv", "cost_distance", "", "cost_direction", "", "", "", "", "") print("Cost distance") # --- Least cost path arcpy.gp.CostPath_sa("min_point", "cost_distance", "cost_direction", "cost_path", "EACH_CELL", "") print("Least cost path") # --- Convert result to polyline arcpy.RasterToPolyline_conversion(in_raster="cost_path", out_polyline_features="line", background_value="ZERO", minimum_dangle_length="0", simplify="SIMPLIFY", raster_field="Value") # --- Unsplit lines arcpy.Dissolve_management(in_features="line", out_feature_class="output", dissolve_field="", statistics_fields="", multi_part="MULTI_PART", unsplit_lines="UNSPLIT_LINES") # --- Add field arcpy.AddField_management(in_table="output", field_name="reference", field_type="LONG", field_is_required="NON_REQUIRED") # Add value to reference field arcpy.CalculateField_management(in_table="output", field="reference", expression="%s" %i, expression_type="PYTHON", code_block="") # --- Append to final shapefile arcpy.Append_management(inputs="output", target=length, schema_type="NO_TEST", field_mapping="", subtype="") # time.sleep(1)