def get_hypsometry (feature, dem, workspace, raster_scaling = 1000, max_bin = 8850, min_bin = 0, bin_size = 50):
    """Calculate hypsometry information from the given digital elevation model
    (DEM) and return bin statistics. If this function fails at runtime an error
    is returned for recording in the log file."""
    hypsometry = []
    try:
        reclassify_range = '' # re-map string
        elevation_list = []   # List containing the area and elevation values
            
        # Generate re-map string for the reclassify function. This done by first
        # calculating the number of bins and then finding the low and high values
        # for each bin and then giving it a label.
        total_bins = round(math.ceil(float(max_bin - min_bin) / float(bin_size)), 0)
        for bin_num in range (0, int(total_bins)):  # For each bin...
            low_value =  bin_num * bin_size         # Low value in range and re-map value
            high = float((bin_num + 1) * bin_size)  # High value in range
            reclassify_range += str(float(low_value)) + " " + str(high) + " " + str(low_value) + ";"
            
            hypsometry.append(float(low_value)) # Append the bin value to the hypsometry list
    
        # Reclassify the DEM based on bins
        reclassify =  workspace + '\\' + 'Reclassify_Raster_' + str(feature.GLIMSID) + '.img'
        reclass_raster = spatial.Reclassify (dem, "Value", reclassify_range, "NODATA")
        reclass_raster.save(reclassify)
        
        # Create a clipped feature from the input raster.
        bin_features = raster_to_polygon(feature, reclassify, workspace, raster_scaling)
        
        # Iterate over the feature table and generate a list of bin values and area of each
        rows = ARCPY.SearchCursor(bin_features)
        for row in rows:
            elevation_list.append([float(row.GRIDCODE/raster_scaling), float(row.F_AREA)])
        del row, rows
            
        item_found = False # Switch to identify if an element exists or not
        current_bin = 0.0 # Bin value to print
        for index, hypso_bin in enumerate (hypsometry): # For each hypsometry bin
            for item in elevation_list:      # Loop through the elevation list 
                if item[0] == hypso_bin:        # If the value in elev. List is found...
                    current_bin += item[1]      # ... add it to the hypsometry list
                    item_found = True
                    
            if item_found == False: # If an element is NOT found in elevation list...
                hypsometry[index] = str(0.0) # set elevation bin to 0.0
            else:                   # If an element is found
                # Set elevation bin to sum of values and remove decimals by rounding
                hypsometry[index] = str(round(current_bin, 0)) 
                item_found = False  # Reset the switch
                current_bin = 0.0   # Reset bin value to print
        
        ARCPY.Delete_management(reclassify) # Remove the reclassified raster from workspace
        
        return hypsometry, False, bin_features
    except:
        return hypsometry, True, False
Exemple #2
0
def bin_by_dem(feature, dem, scratch, name=None, bin_size=50):
    """Calculate bins  from the given digital elevation model
    (DEM) and return bin statistics."""
    # Build Export Name. This option is largely included in case there is unexpected
    # naming conflicts with other functions
    if name == '' or name == None: name = os.path.join(scratch, 'Binned.shp')
    else: name = os.path.join(scratch, name)

    min_bin = 0  # Force default min_bin to sea level. DO NOT CHANGE.
    max_bin = 8850

    reclassify_range = ''  # re-map string
    # Generate re-map string for the reclassify function. This done by first
    # calculating the number of bins and then finding the low and high values
    # for each bin and then giving it a label.
    total_bins = round(math.ceil(float(max_bin - min_bin) / float(bin_size)),
                       0)
    for bin_num in range(0, int(total_bins)):  # For each bin...
        low_value = bin_num * bin_size  # Low value in range and re-map value
        high_value = (bin_num + 1) * bin_size  # High value in range
        reclassify_range += str(float(low_value)) + " " + str(
            float(high_value)) + " " + str(low_value) + ";"

    # Reclassify the DEM based on bins
    filled = spatial.Fill(dem)  # Fill DEM
    reclass_raster = spatial.Reclassify(filled, "Value", reclassify_range,
                                        "NODATA")

    # Create a clipped feature from the input raster.
    poly_raster = raster_to_polygon(feature, reclass_raster, scratch, '', 1)

    # Clip and clean to the original input feature
    arcpy.Clip_analysis(poly_raster, feature, name)

    # Format output table.
    to_delete = get_fields(name)
    fields = [('BINS', 'INTEGER', "'!grid_code!'"),
              ('STEP_SIZE', 'INTEGER', bin_size)]
    for field in fields:
        arcpy.AddField_management(name, field[0], field[1])
        arcpy.CalculateField_management(name, field[0], field[2], 'PYTHON')
    for item in to_delete:
        arcpy.DeleteField_management(name, item)

    arcpy.Delete_management(filled)
    arcpy.Delete_management(poly_raster)
    return name
    if debug == True:
        arcpy.AddMessage(
            str(
                time.strftime("copyraster: %m/%d/%Y  %H:%M:%S",
                              time.localtime())))
    scratchSlope = os.path.join("in_memory", "scratchSlope")
    arcpy.CopyRaster_management("SlopeLayer", scratchSlope)
    deleteme.append(scratchSlope)
    reclassSlope = os.path.join(scratch, "reclassSlope")
    if debug == True:
        arcpy.AddMessage(
            str(
                time.strftime("Reclassify: %m/%d/%Y  %H:%M:%S",
                              time.localtime())))
    arcpy.AddMessage("Reclassifying slope...")
    reclass = sa.Reclassify(scratchSlope, "VALUE", remap, missing_values)
    reclass.save(reclassSlope)
    deleteme.append(reclassSlope)
    #clean edges
    boundaryClean = os.path.join(scratch, "boundaryClean")
    if debug == True:
        arcpy.AddMessage(
            str(
                time.strftime("BoundaryClean: %m/%d/%Y  %H:%M:%S",
                              time.localtime())))
    clean = sa.BoundaryClean(reclassSlope, "NO_SORT", "TWO_WAY")
    clean.save(boundaryClean)
    deleteme.append(boundaryClean)

    # Convert reclassified slope ranges to polygon features
    slopePoly = os.path.join(scratch, "slopePoly")
Exemple #4
0
tciRaster1 = sa.Ln(sa.Plus(flacRaster, 30.0) / sa.Tan(slopeRad))
# Where slope is zero, set TCI to its max value
tciRaster = sa.Con(slopeRad, tciRaster1.maximum, tciRaster1, "Value = 0")

# Create class breaks according to the method selected
if parseMethod in ("EQUAL_INTERVAL", "EQUAL_AREA"):
    msg("Using equal interval breaks")
    #Slice values
    msg("...decomposing values into equal quantiles")
    elevSlice = sa.Slice(elevRaster, 5, parseMethod, 1) * 100
    solSlice = sa.Slice(solRaster, 5, parseMethod, 1)
    tciSlice = sa.Slice(tciRaster, 5, parseMethod, 1)
    # Remap the extremes of the solar and tci rasters
    msg("...recoding group values")
    remap = sa.RemapValue([[1, 1], [2, 2], [3, 2], [4, 2], [5, 3]])
    solRemap = sa.Reclassify(solSlice, "VALUE", remap) * 10
    tciRemap = sa.Reclassify(tciSlice, "VALUE", remap)
    # Combine into zip codes
    msg("...combining values into zip codes")
    msg("Computing zipcodes")
    zipCodes = elevSlice + solRemap + tciRemap
    zipCodes.save(zipCodeRaster)
    msg("Output saved to %s" % zipCodeRaster)
elif parseMethod == ("EO BREAKS"):
    msg("Using natural breaks informed by element occurrences")
    # Create a feature class of Plant EOs with good precision
    whereClause = "\"UNCRT_DIST\" <= 1000 AND \"NAME_CATGY\" IN ( 'Vascular Plant', 'Nonvascular Plant', 'Natural Community')"
    plantEOs = arcpy.MakeFeatureLayer_management(EOs, "plantEOs", whereClause)

    # Find class breaks using EO locations
    msg("Extracting data at element occurrence locations")
Exemple #5
0
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!")