def cc_copy_inputs(): """Clip Climate Linkage Mapper inputs to smallest extent""" lm_util.gprint("\nCOPYING LAYERS AND, IF NECESSARY, REDUCING EXTENT") ext_poly = "ext_poly" # Extent polygon climate_extent = arcpy.Raster(cc_env.climate_rast).extent if cc_env.resist_rast is not None: resist_extent = arcpy.Raster(cc_env.resist_rast).extent xmin = max(climate_extent.XMin, resist_extent.XMin) ymin = max(climate_extent.YMin, resist_extent.YMin) xmax = min(climate_extent.XMax, resist_extent.XMax) ymax = min(climate_extent.YMax, resist_extent.YMax) # Set to minimum extent if resistance raster was given arcpy.env.extent = arcpy.Extent(xmin, ymin, xmax, ymax) # Want climate and resistance rasters in same spatial ref # with same nodata cells proj_resist_rast = sa.Con(sa.IsNull(cc_env.climate_rast), sa.Int(cc_env.climate_rast), cc_env.resist_rast) proj_resist_rast.save(cc_env.prj_resist_rast) else: xmin = climate_extent.XMin ymin = climate_extent.YMin xmax = climate_extent.XMax ymax = climate_extent.YMax ones_resist_rast = sa.Con(sa.IsNull(cc_env.climate_rast), sa.Int(cc_env.climate_rast), 1) ones_resist_rast.save(cc_env.prj_resist_rast) arcpy.CopyRaster_management(cc_env.climate_rast, cc_env.prj_climate_rast) # Create core raster arcpy.env.extent = arcpy.Extent(xmin, ymin, xmax, ymax) lm_util.delete_data(cc_env.prj_core_rast) arcpy.FeatureToRaster_conversion( cc_env.core_fc, cc_env.core_fld, cc_env.prj_core_rast, arcpy.Describe(cc_env.climate_rast).MeanCellHeight) arcpy.env.extent = None # Create array of boundary points array = arcpy.Array() pnt = arcpy.Point(xmin, ymin) array.add(pnt) pnt = arcpy.Point(xmax, ymin) array.add(pnt) pnt = arcpy.Point(xmax, ymax) array.add(pnt) pnt = arcpy.Point(xmin, ymax) array.add(pnt) # Add in the first point of the array again to close polygon boundary array.add(array.getObject(0)) # Create a polygon geometry object using the array object ext_feat = arcpy.Polygon(array) arcpy.CopyFeatures_management(ext_feat, ext_poly) # Clip core feature class arcpy.Clip_analysis(cc_env.core_fc, ext_poly, cc_env.prj_core_fc)
def raster_to_polygon(feature, raster, scratch, name=None, raster_scaling=1000): """Convert raster to a features class, clip it to an input feature and calculate the area of each polygon. This new feature class is then returned for calculating statistics. """ # Build Export Name. This option is largely included in case there is unexpected # naming conflicts with other functions if name == '' or name == None: polygon = os.path.join(scratch, 'Raster_to_Polygon.shp') else: polygon = os.path.join(scratch, name) # Scale the subset DEM and temporarily save it to file. If it is not # saved, a VAT error is sometimes thrown when converting to polygon. subset = spatial.Int(raster * raster_scaling) converted = arcpy.RasterToPolygon_conversion(subset, 'in_memory\\rtp_result', 'NO_SIMPLIFY') arcpy.Clip_analysis(converted, feature, polygon) arcpy.Delete_management(subset) arcpy.Delete_management(converted) return polygon
def convert_to_integer(self, in_raster, out_raster): """ Converts a floating point raster to an integer raster Parameters ---------- in_raster : str name of floating point raster to convert to int out_raster : str name of output converted raster Returns ------- None """ print('Converting ' + in_raster + ' to integer') try: # create an integer grid scratch = sa.Int(sa.RoundDown((sa.Raster(in_raster) * 100) + 0.5)) scratch.save(out_raster) except: raise Exception(arcpy.GetMessages())
def raster_to_polygon (feature, raster, workspace, raster_scaling = 1000): """Convert raster to a features class, clip it to an input feature and calculate the area of each polygon. This new feature class is then returned for calculating statistics. """ # Scale the subset DEM and temporarily save it to file. If it is not # saved an error is sometimes thrown when converting to polygon. # This is no good reason for this VAT error. rand_id = str(random.randrange(10000, 999999)) subset_name = workspace + '\\raster_to_poly_' + rand_id + '.img' subset = spatial.Int(spatial.Raster(raster) * raster_scaling + 0.5) subset.save(subset_name) polygon = ARCPY.RasterToPolygon_conversion(subset, subset_name, "NO_SIMPLIFY") clipped = ARCPY.Clip_analysis(polygon, feature.shape, 'in_memory\\clip_' + rand_id) feature = ARCPY.CalculateAreas_stats(clipped, 'in_memory\\area_'+ rand_id) ARCPY.Delete_management(subset) ARCPY.Delete_management(polygon) ARCPY.Delete_management(clipped) return feature
try: elevSheds = sa.Watershed(fldrRaster, strmElevRaster, "VALUE") except: msg(arcpy.GetMessages(), "error") sys.exit(1) msg("Identifying cells within {}m in elevation from stream cell".format( zThreshold)) elevDiff = sa.Minus(elevRaster, elevSheds) # Reduce NLCD to level 1, if not already if int( arcpy.GetRasterProperties_management(nlcdRaster, "MAXIMUM").getOutput(0)) > 10: msg("Simplifying land cover to level 1") nlcdLevel1 = sa.Int(arcpy.Raster(nlcdRaster) / (10)) else: nlcdLevel1 = nlcdRaster msg("Extracting land cover within riparian cells") riparianNLCD = sa.SetNull(elevDiff, nlcdLevel1, 'VALUE > {}'.format(zThreshold)) ## If no forest or riparian exists msg("Tabulating area of each NLCD cover within each catchment") arcpy.sa.TabulateArea(catchRaster, "VALUE", riparianNLCD, "VALUE", riparianTbl) msg("...calculating percents from areas names") for x in (1, 2, 3, 4, 5, 7, 8, 9): pctFldName = "Riparian_{}P".format(x) #Create the pct area calculation string
OUT_PATH = BASE_OUT_PATH + "/j_disks_contrib_int" if not os.path.exists(OUT_PATH): os.makedirs(OUT_PATH) print "cleaning up contrib area raster" ENV.workspace = IN_PATH RasList = arcpy.ListRasters("*", "TIF") for ras in RasList: lyrName = ras[:-7] print lyrName inRas = IN_PATH + "/" + ras outRas = OUT_PATH + "/" + lyrName + "_ci.tif" #contributing area integer result = SA.Int((arcpy.Raster(inRas) * 0) + 1) result.save(outRas) #%% # now convert to poly IN_PATH = BASE_OUT_PATH + "/j_disks_contrib_int" OUT_PATH = BASE_OUT_PATH + "/k_pols_contribArea" if not os.path.exists(OUT_PATH): os.makedirs(OUT_PATH) print "converting to polygon" ENV.workspace = IN_PATH RasList = arcpy.ListRasters("*", "TIF")
# Loop through each patchID in the PatchIDList for patchID in patchIDs: iter = iter + 1 if iter > interval: msg(" %d%% complete." %(float(iter/total)*100.0)) interval = interval + interval2 # - Isolate the TO patch selectedPatch = sa.SetNull(patchRaster, patchRaster, "Value <> %s" %patchID) # - If saving outputs, set the back link raster name if saveRasters == 'true': backLink = os.path.join(saveRasterLocation,"BL_%s.img" %patchID) # - Calculate a cost distance and cost back link raster to the selected patch costDist = sa.CostDistance(selectedPatch, costRaster, maxDist, backLink) # - If saving outputs, save the cost distance as an integer raster if saveRasters == 'true': cdInt = sa.Int(costDist) #Convert to integer raster to save space cdInt.save(os.path.join(saveRasterLocation,"CD_%s.img" %patchID)) # - Tabulate zonal stats for the other patches on the cost distance zStatTable = sa.ZonalStatisticsAsTable(patchRaster,"Value",costDist,"in_memory\zstattbl","DATA","MINIMUM") # - 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
def krigingFromPointCSV(inTable, valueField, xField, yField, inClipFc, workspace = "assignment3.gdb"): # Import necessary modules import arcpy import arcpy.sa as sa import os import sys import traceback # Allow overwriting arcpy.env.overwriteOutput = True # Set workspace environment arcpy.env.workspace = workspace # Define custom exceptions class WorkspaceExistsError(Exception): pass class inTableExistsError(Exception): pass class valueFieldExistsError(Exception): pass class xFieldExistsError(Exception): pass class yFieldExistsError(Exception): pass class inClipFcExistsError(Exception): pass class inClipFcShapeError(Exception): pass class LicenseError(Exception): pass # Check that all specified files exist and parameters are valid try: # Test if workspace exists if arcpy.Exists(workspace): print("Specified workspace has been found.") else: raise WorkspaceExistsError # Test if inTable exists if arcpy.Exists(inTable): print("Specified table has been found.") else: raise inTableExistsError # Test if valueField, xField, and yField exist in inTable fields = arcpy.ListFields(inTable) fieldstest = [] for f in fields: fieldstest.append(f.name) if valueField in fieldstest: print("Specified value field has been found in the table.") else: raise valueFieldExistsError if xField in fieldstest: print("Specified x field has been found in the table.") else: raise xFieldExistsError if yField in fieldstest: print("Specified y field has been found in the table.") else: raise yFieldExistsError # Test if inClipFc exists if arcpy.Exists(inClipFc): print("Specified feature class has been found.") else: raise inClipFcExistsError # Test if polygon feature class shapeType parameter is valid descclip = arcpy.Describe(inClipFc) if descclip.shapeType != "Polygon": raise inClipFcShapeError else: print("Specified feature class has the correct shape type for this script (polygon).") # Check for Spatial Analyst license if arcpy.CheckExtension("Spatial") == "Available": arcpy.CheckOutExtension("Spatial") print("Spatial Analyst license recognized.") else: raise LicenseError except WorkspaceExistsError: print("WorkspaceExistsError: The specified workspace could not be found!") except inTableExistsError: print("inTableExistsError: The specified table could not be found!") except valueFieldExistsError: print("valueFieldExistsError: The specified value field could not be found!") except xFieldExistsError: print("xFieldExistsError: The specified x field could not be found!") except yFieldExistsError: print("yFieldExistsError: The specified y field could not be found!") except inClipFcExistsError: print("inClipFcExistsError: The specified feature class could not be found!") except inClipFcShapeError: print("inClipFcShapeError: The specified feature class must be a polygon shape type!") except LicenseError: print("LicenseError: Spatial Analyst license is unavailable!") # If no exceptions are raised, attempt to carry out the procedure else: try: # Generate an input feature layer using inTable points = inTable + "_points" arcpy.management.XYTableToPoint(inTable, points, xField, yField) print("Point layer created.") # Create spatial reference object for inClipFc spatial_ref = descclip.spatialReference # Project the points feature layer to the system used by inClipFc prjpoints = inTable + "_prjpoints" arcpy.management.Project(points, prjpoints, spatial_ref) print("Point layer projected to match input polygon feature class.") # Create a cellSize variable based on the extent descpoints = arcpy.Describe(prjpoints) cellSize = 0 width = descpoints.extent.width height = descpoints.extent.height if width < height: cellSize = width / 1000 else: cellSize = height / 1000 # Naming convention for kriging output kname = valueField + "_K" # Interpolate raster surface from points using kriging and save the output outKriging = sa.Kriging(prjpoints, valueField, '#', cellSize) outKriging.save(kname) print("Points interpolated to create raster.") # Define bounding box rectangle rectangle = str(descclip.extent.XMin) + " " + str(descclip.extent.YMin) + " " + str(descclip.extent.XMax) + " " + str(descclip.extent.YMax) # Naming convention for clipped kriging output cname = kname + "_C" # Clip the kriging output using the defined feature class arcpy.Clip_management(kname, rectangle, cname, inClipFc, "#", "ClippingGeometry", "MAINTAIN_EXTENT") print("Raster layer clipped.") # Naming convention for integerized raster iname = cname + "_I" # Truncate raster cell values to integers and save the output outInt = sa.Int(cname) outInt.save(iname) print("Clipped raster layer values truncated to integers.") # Get minimum and maximum cell values min_F2018 = arcpy.management.GetRasterProperties(outInt, "MINIMUM") max_F2018 = arcpy.management.GetRasterProperties(outInt, "MAXIMUM") min_2018 = int(min_F2018.getOutput(0)) max_2018 = int(max_F2018.getOutput(0)) # Define the number of classes to use numofclasses = 5 # Use number of classes and min and max values to calculate equal intervals eq_interval = (max_2018 - min_2018) / numofclasses # Create classification scheme remapRangeList = [] mybreak = min_2018 for i in range(0, numofclasses): newClassCode = i + 1 lowerBound = int(mybreak) upperBound = int(mybreak + eq_interval) remap = [lowerBound, upperBound, newClassCode] remapRangeList.append(remap) mybreak += eq_interval # Reclassify the raster rname = iname + "_R" outReclassRR = sa.Reclassify(iname, "Value", sa.RemapRange(remapRangeList), "NODATA") outReclassRR.save(rname) print("Raster values reclassified.") # Convert the raster into a polygon feature class arcpy.RasterToPolygon_conversion(rname, valueField + "_ismc") print("Raster converted to vector (polygon feature class).") # Delete unnecessary intermediate stages del1 = os.path.join(workspace, points) del2 = os.path.join(workspace, prjpoints) del3 = os.path.join(workspace, kname) del4 = os.path.join(workspace, cname) del5 = os.path.join(workspace, iname) del6 = os.path.join(workspace, rname) arcpy.management.Delete([del1,del2,del3,del4,del5,del6]) print("Unnecessary files deleted.") # Catch-all exception handling except arcpy.ExecuteError: # Get the tool error messages msgs = arcpy.GetMessages(2) # Return tool error messages for use with a script tool arcpy.AddError(msgs) # Print tool error messages for use in Python print("Tool Error:", msgs) except: # Get the traceback object tb = sys.exc_info()[2] tbinfo = traceback.format_tb(tb)[0] # Put error information into a message string pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1]) msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n" # Return python error messages for use in script tool or Python window arcpy.AddError(pymsg) arcpy.AddError(msgs) # Print Python error messages for use in Python / Python window print(pymsg) print(msgs) else: print("All script operations now complete!")
# outputs flowlengthOutput = sys.argv[6] # Decayed flow wtdOutput = sys.argv[7] # Decay weighted output # Message function def msg(txt): print txt; arcpy.AddMessage(txt); return ##-PROCESSES- # 1. Convert curve number to a weight: Int((100 - cn) / 10). Higher CN values # reflect increased runoff across the cell. This equation inverts the # CN value and scales it to values from 0 to 10. The resulting value reflects # a proxy for infiltration: higher values suggest more runoff stays in the cell # meaning less pollutants will leave the cell to downstream neighbors. msg("Calculating flow length weight from %s" %cnRaster) weightRaster = sa.Int(sa.Divide(sa.Minus(100.0,cnRaster), 10.0) + 1) # 2. Create a flow direction where streams are NoData. This enables calculation # of flow length to the stream vs to the stream outlet. msg("Creating modified flow direction to calculate distance to streams") fdRaster = sa.Con(sa.IsNull(streamsRaster),flowdirRaster) # 3. Calculate cost-weighted flowlength. Cell values represent the infiltrated- # weighted distance along the flow path to a stream. Two paths may be the same # length, but if one goes through cells with high curve numbers (low weights) # it's path will be effectively shorter whereas a path going through cells with # low curve numbers (high weights) will be effectively longer - in terms of # suspended/dissolved pollutants reaching the stream. msg("Calculating weighted flow length") wtdflRaster1 = sa.FlowLength(fdRaster,"DOWNSTREAM",weightRaster) + 30 #Set stream pixels to 0