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
        desc = ARCPY.Describe(feature)
        XMin_new = desc.extent.XMin - 200
        YMin_new = desc.extent.YMin - 200
        XMax_new = desc.extent.XMax + 200
        YMax_new = desc.extent.YMax + 200
        ARCPY.env.extent = 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 = spatial.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 = spatial.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 = spatial.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 =spatial.EucDistance(polyline, "", eu_cell_size, '')
         
        masked_eucdist = spatial.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 = spatial.CostDistance(minimum_point, cost_raster, '', backlink) 
        cost_path = spatial.CostPath(maximum_point, cost_distance, backlink, 'EACH_CELL', '')
        cost_path_ones = spatial.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
    # taken from The Polygon to Centerline Tool for ArcGIS (trim skeletons). (Dilts. 2015.)
    # Process: Dissolve
    arcpy.AddMessage("Step 12/12 Started- Dissolving Lines")
    arcpy.Dissolve_management(Thiessen_Lines_Layer__3_,
                              Thiessen_Lines_Dissolve1_shp, "GRIDCODE", "",
                              "MULTI_PART", "DISSOLVE_LINES")
    arcpy.AddMessage("Step 12/12 Completed")

    # Process: Multipart To Singlepart
    arcpy.AddMessage("Line Trimming Started")
    arcpy.MultipartToSinglepart_management(Thiessen_Lines_Dissolve1_shp,
                                           CentreLine)

    # Process: Trim Line
    arcpy.TrimLine_edit(CentreLine, "", "DELETE_SHORT")
    arcpy.AddMessage("Line Trimming Completed")
    #end of section from Dilts. 2015

#if line trim not selected just dissolve the lines
else:
    # Process: Dissolve
    arcpy.AddMessage("Step 12/12 Started- Dissolving Lines")
    arcpy.Dissolve_management(Thiessen_Lines_Layer__3_, CentreLine, "GRIDCODE",
                              "", "MULTI_PART", "DISSOLVE_LINES")
    arcpy.AddMessage("Step 12/12 Completed")

#check if features have been selected and run if so
if featurecheck:

    # Local variables:
def createpolyfeatureclass_2d(mainpolylist_2d, postbottomboxlist_2d, minsfirst,
                              minslast, maxfirst, maxlast, prior,
                              ExtendLine_edit_distance,
                              TrimLine_edit_dangle_length,
                              Integrate_management_distance, smooth_2d):
    '''
    arcpy.ExtendLine_edit(joinadd("in_memory","all_lines_2d_dissolved"),"5")
    ExtendLine_edit_distance=The maximum distance a line segment can be extended to an intersecting feature.
    arcpy.TrimLine_edit (joinadd("in_memory","all_lines_2d_dissolved"),"2", "kEEP_SHORT")
    TrimLine_edit_dangle_length=Line segments that are shorter than the specified Dangle Length and do not touch another line at both endpoints (dangles) will be trimmed.
    arcpy.Integrate_management(joinadd("in_memory","all_lines_2d_dissolved"), 0.01)
    Integrate_management_distance=The distance that determines the range in which feature vertices aremade coincident. To minimize undesired movement of vertices, the x,ytolerance should be fairly small.
    '''
    #arcpy.CreateFeatureclass_management("C:\Users\usuari\Desktop\Interpretation-test01-2018.mdb", "mainpolyli", "POLYLINE","", "DISABLED", "ENABLED")
    allpolies = list()
    infpolies = list()
    ##################
    'filenames1'
    homeadd = joinadd(expanduser("~"), "arcgistemp_2d")
    #plnsadd=joinadd(homeadd,"plns_2d")
    #################
    'making  priorpolylist [ priority number, [polyline1,polyline2,...] ]'
    for i in range(0, len(mainpolylist_2d)):
        for j in mainpolylist_2d[i][2]:
            allpolies.append([j[0], j[2]])
    #######
    #postbottomboxlist=[ [point1coord,point2coord,point 1 borehole or mid (0 or 1) ,point 2 borehole or mid (0 or 1), polyline] ,... ]
    for kk in postbottomboxlist_2d:
        allpolies.append(["post_bottombox_2d", kk[4]])
    ######
    pointlist = [maxfirst, minsfirst[1]]
    firstbhline_2d = arcpy.Polyline(
        arcpy.Array([arcpy.Point(*coords) for coords in pointlist]), "Unknown",
        False, False)
    allpolies.append(["firstbhline_2d", firstbhline_2d])

    pointlist = [maxlast, minslast[1]]
    lastbhline_2d = arcpy.Polyline(
        arcpy.Array([arcpy.Point(*coords) for coords in pointlist]), "Unknown",
        False, False)
    allpolies.append(["lastbhline_2d", lastbhline_2d])

    #######

    priorpolylist = list()
    #print 'allpolies is:', allpolies

    for n in allpolies:
        if [n[0], []] not in priorpolylist:
            priorpolylist.append([n[0], []])

    for m in priorpolylist:
        for b in allpolies:
            if b[0] == m[0]:

                m[1].append(b[1])

    #print 'priorpolylist_2d' , priorpolylist
    ###################
    'creating the main polyline featureclass'

    con = 0
    polylineadlistmerge = []
    polylineadlistmerge_smooth = []
    arcpy.CreateFeatureclass_management("in_memory", "all_lines_2d",
                                        "POLYLINE", "", "DISABLED", "DISABLED",
                                        "")
    for ii in range(0, len(priorpolylist)):
        con = con + 1

        'names'
        temppolyname = "temppoly_2d" + str(con)
        #plnslayername=joinadd(homeadd,"plnslayer_2d")+str(con)+".shp"
        #mainplnsadd=joinadd(homeadd,"mainplns_2d")+str(con)+".shp"
        #mainplnsadd2=joinadd(homeadd,"mainplns_2d")+str(con+1)
        ############
        arcpy.CreateFeatureclass_management("in_memory", temppolyname,
                                            "POLYLINE", "", "DISABLED",
                                            "DISABLED", "")

        cursor = arcpy.da.InsertCursor(joinadd("in_memory", temppolyname),
                                       ["SHAPE@"])
        for t in priorpolylist[ii][1]:
            cursor.insertRow([t])
        del cursor
        ############### test 2019
        cursor = arcpy.da.InsertCursor(joinadd("in_memory", "all_lines_2d"),
                                       ["SHAPE@"])
        for t in priorpolylist[ii][1]:
            cursor.insertRow([t])
        del cursor
        ###################
        #dissolve:basic
        #integrate: basic
        #ExtendLine_edit: standard
        #TrimLine_edit: standard
        #Integrate_management:basic
        #RepairGeometry_management:basic
        #FeatureToPolygon_management: advanced
        #
        arcpy.Dissolve_management(
            joinadd("in_memory", temppolyname),
            joinadd("in_memory", "plnslayertemp_2d" + str(con)), "", "", "",
            "UNSPLIT_LINES")
        arcpy.Integrate_management(
            joinadd("in_memory", "plnslayertemp_2d" + str(con)), 0.01)
        polylineadlistmerge.append(
            joinadd("in_memory", "plnslayertemp_2d" + str(con)))
        #arcpy.FeatureVerticesToPoints_management(joinadd("in_memory","plnslayertemp_2d"+str(con)),joinadd(homeadd,"dangle"+str(con)),"DANGLE")
        ################
        if smooth_2d == True:
            #smoothing
            arcpy.SmoothLine_cartography(
                joinadd("in_memory", "plnslayertemp_2d" + str(con)),
                joinadd("in_memory", "smoothed" + str(con)),
                "BEZIER_INTERPOLATION", "", "FIXED_CLOSED_ENDPOINT", "")
            polylineadlistmerge_smooth.append(
                joinadd("in_memory", "smoothed" + str(con)))
    #############test 2019
    arcpy.Dissolve_management(joinadd("in_memory", "all_lines_2d"),
                              joinadd("in_memory", "all_lines_2d_dissolved"),
                              "", "", "", "UNSPLIT_LINES")
    arcpy.ExtendLine_edit(joinadd("in_memory", "all_lines_2d_dissolved"),
                          str(ExtendLine_edit_distance))
    arcpy.TrimLine_edit(joinadd("in_memory", "all_lines_2d_dissolved"),
                        str(TrimLine_edit_dangle_length), "kEEP_SHORT")
    arcpy.Integrate_management(joinadd("in_memory", "all_lines_2d_dissolved"),
                               Integrate_management_distance)
    arcpy.RepairGeometry_management(
        joinadd("in_memory", "all_lines_2d_dissolved"))
    arcpy.FeatureToPolygon_management(
        joinadd("in_memory", "all_lines_2d_dissolved"),
        joinadd("in_memory", "all_lines_2d_dissolved_feat_to_poly"), "0.02",
        "", "")
    polylineadlistmerge.append(
        joinadd("in_memory", "all_lines_2d_dissolved_feat_to_poly"))
    ###################
    #smoothing
    if smooth_2d == True:
        arcpy.SmoothLine_cartography(
            joinadd("in_memory", "all_lines_2d_dissolved"),
            joinadd("in_memory", "all_lines_2d_dissolved_smoothed"),
            "BEZIER_INTERPOLATION", "", "FIXED_CLOSED_ENDPOINT", "")
        arcpy.FeatureToPolygon_management(
            joinadd("in_memory", "all_lines_2d_dissolved_smoothed"),
            joinadd("in_memory",
                    "all_lines_2d_dissolved_feat_to_poly_smoothed"), "0.02",
            "", "")
        polylineadlistmerge_smooth.append(
            joinadd("in_memory",
                    "all_lines_2d_dissolved_feat_to_poly_smoothed"))
        arcpy.CreateFileGDB_management(homeadd, "arcgistempdb_2d_smoothed.gdb")
        arcpy.FeatureClassToGeodatabase_conversion(
            polylineadlistmerge_smooth,
            joinadd(homeadd, "arcgistempdb_2d_smoothed.gdb"))
    ###################
    mergedpolygonsfromlines_2d = joinadd("in_memory",
                                         "mergedpolygonsfromlines_2d")

    arcgistempdb_2d = joinadd(homeadd, "arcgistempdb_2d.gdb")

    arcpy.FeatureToPolygon_management(polylineadlistmerge,
                                      mergedpolygonsfromlines_2d, "", "", "")

    polylineadlistmerge.append(mergedpolygonsfromlines_2d)
    arcpy.CreateFileGDB_management(homeadd, "arcgistempdb_2d.gdb")
    arcpy.FeatureClassToGeodatabase_conversion(polylineadlistmerge,
                                               arcgistempdb_2d)
    #####################
    return arcgistempdb_2d
        if trim == 'true':
            arcpy.AddMessage('Triming Lines')
            
            trim_dist = {}
            with arcpy.da.SearchCursor(outfc, ["Sample_No_","Distance"]) as cursor:
                for feature in cursor:
                    ID = feature[0]
                    dist = feature[1]
                    if ID in trim_dist:
                        if dist < trim_dist[ID]:
                            trim_dist[ID] = dist
                    else:
                        trim_dist[ID] = dist
	    del cursor,feature

            arcpy.TrimLine_edit(outfc)

            with arcpy.da.UpdateCursor(outfc,["Sample_No_","Distance"]) as cursor:
                for feature in cursor:
                    try:
                        ID = feature[0]
                        dist = feature[1] - trim_dist[ID]

                        feature[1] = dist
            
                        cursor.updateRow(feature)
                    except Exception,e: #No Connection?
                        arcpy.AddError('%s'%(e))
                        break
	    del cursor,feature
def area_cut(roads_in, widths_in, area_in, output_dir_in, output_name_in):
    """
    This function cuts the input lines feature class (roads, streets, anything) into a square shape around the median 
    point of the input lines feature class. It saves the polygon (the square itself) to the specified output location,
    the cut streets and intersections are saved to the in_memory workspace as they will be further processed afterwords 
    in the graph analysis. 

    :param roads_in:    line feature class that will be cut
    :param widths_in:   the size of the area in meters   
    :param area_in:     the area in km^2 as in the procedural area generation 
    :param output_dir_in:   path, where to save the results
    :param output_name_in: 
    :return: paths to the resulting feature classes - polygon square, lines, intersections
    """
    arcpy.overwriteOutput = 1

    # Transform roads (lines) into a polygon
    area_path = os.path.join('in_memory', 'area')
    check_exists(area_path)

    area = arcpy.FeatureToPolygon_management(roads_in, area_path)

    # Dissolve a multipart polygon
    area_dissolved_path = os.path.join('in_memory', 'area_dissolved')
    check_exists(area_dissolved_path)

    arcpy.Dissolve_management(area, area_dissolved_path)

    # Get central point
    centroid_path = os.path.join('in_memory', 'centroid')
    check_exists(centroid_path)

    arcpy.arcpy.FeatureToPoint_management(area_dissolved_path, centroid_path)

    # Create a circular buffer around with the radius of half of the needed width
    buffer_out = os.path.join('in_memory', 'buffer')
    check_exists(buffer_out)

    width = str(widths_in) + ' Meters'
    arcpy.Buffer_analysis(centroid_path, buffer_out, width)

    # Create a square from the circular buffer
    square_path = os.path.join(
        output_dir_in, '{0}_area{1}_ply'.format(output_name_in, area_in))
    check_exists(square_path)

    arcpy.FeatureEnvelopeToPolygon_management(buffer_out, square_path)

    # Cut roads
    name_streets_out = os.path.join(
        output_dir_in, '{0}_area{1}_streets'.format(output_name_in, area_in))
    check_exists(name_streets_out)
    arcpy.Clip_analysis(roads_in, square_path, name_streets_out)

    arcpy.TrimLine_edit(name_streets_out)
    arcpy.TrimLine_edit(name_streets_out)
    arcpy.TrimLine_edit(name_streets_out)

    # Get intersections
    out_feature_class = os.path.join('in_memory', 'intersections_tmp')
    arcpy.Intersect_analysis(name_streets_out,
                             out_feature_class,
                             output_type='POINT')
    arcpy.DeleteIdentical_management(out_feature_class, 'Shape')

    name_intersections_out = os.path.join(
        output_dir_in,
        '{0}_area{1}_intersections'.format(output_name_in, area_in))
    check_exists(name_intersections_out)
    arcpy.FeatureToPoint_management(out_feature_class, name_intersections_out)

    return square_path, name_streets_out, name_intersections_out
Exemple #6
0
def main(infc, field, dangle, short, trim, extend, join, loops, output,
         output2):
    try:
        field = field.split(';')
        if field[0] == '':
            field = field[0]
        arcpy.FeatureToLine_management([infc], "in_memory\\templines")

        arcpy.RepairGeometry_management("in_memory\\templines")

        d = dangle.split(" ")

        if eval(d[0]) > 0:

            if trim == 'true':
                arcpy.AddMessage('Triming fracture networks by dangle length')
                arcpy.TrimLine_edit("in_memory\\templines", dangle,
                                    "KEEP_SHORT")

            if join == 'true':

                nodes = {}
                arcpy.AddMessage(
                    'Merging offset fracture networks within dangle length')

                arcpy.FeatureVerticesToPoints_management(
                    "in_memory\\templines", "in_memory\\temppoints",
                    "BOTH_ENDS")

                curfields = [
                    f.name.lower()
                    for f in arcpy.ListFields("in_memory\\temppoints")
                ]

                if 'x' not in curfields:
                    arcpy.AddField_management("in_memory\\temppoints", 'x',
                                              "DOUBLE")

                if 'y' not in curfields:
                    arcpy.AddField_management("in_memory\\temppoints", 'y',
                                              "DOUBLE")

                arcpy.CalculateField_management("in_memory\\temppoints", 'x',
                                                "!SHAPE.CENTROID.X!",
                                                "PYTHON_9.3")
                arcpy.CalculateField_management("in_memory\\temppoints", 'y',
                                                "!SHAPE.CENTROID.y!",
                                                "PYTHON_9.3")

                with arcpy.da.SearchCursor("in_memory\\temppoints",
                                           ['x', 'y']) as cursor:
                    for row in cursor:
                        try:
                            ID = (row[0], row[1])
                            if ID in nodes:
                                value = nodes[ID]
                                value += 1
                                nodes[ID] = value
                            else:
                                nodes[ID] = 1

                        except Exception, e:
                            arcpy.AddError('%s' % (e))
                            continue

                with arcpy.da.UpdateCursor("in_memory\\temppoints",
                                           ['x', 'y']) as cursor:
                    for row in cursor:
                        ID = (row[0], row[1])
                        value = nodes[ID]
                        if value > 1:
                            cursor.deleteRow()
                del nodes

                arcpy.GenerateNearTable_analysis("in_memory\\temppoints",
                                                 "in_memory\\temppoints",
                                                 "in_memory\\temptable",
                                                 dangle, "LOCATION", "", "",
                                                 "")

                Connections = {}
                with arcpy.da.SearchCursor(
                        "in_memory\\temptable",
                    ['FROM_X', 'FROM_Y', 'NEAR_X', 'NEAR_Y']) as cursor:
                    for row in cursor:
                        try:
                            Connections[(row[0], row[1])] = (row[2], row[3])

                        except Exception, e:
                            arcpy.AddError('%s' % (e))
                            continue

                array = arcpy.Array()
                if Connections:
                    Count = 0
                    with arcpy.da.UpdateCursor("in_memory\\templines",
                                               ['SHAPE@']) as cursor:
                        for row in cursor:
                            start = row[0].firstPoint
                            end = row[0].lastPoint
                            branch = (start.X, start.Y)
                            rbranch = (end.X, end.Y)

                            if branch in Connections:
                                Count += 1
                                addgeom = Connections[branch]
                                array.add(arcpy.Point(addgeom[0], addgeom[1]))
                                for part in row[0]:
                                    for pnt in part:
                                        point = (pnt.X, pnt.Y)
                                        array.add(
                                            arcpy.Point(point[0], point[1]))
                                geom = arcpy.Polyline(array)
                                array.removeAll()
                                row[0] = geom
                                cursor.updateRow(row)
                                if addgeom in Connections:
                                    del Connections[addgeom]

                            elif rbranch in Connections:
                                Count += 1
                                addgeom = Connections[rbranch]
                                for part in row[0]:
                                    for pnt in part:
                                        point = (pnt.X, pnt.Y)
                                        array.add(
                                            arcpy.Point(point[0], point[1]))
                                array.add(arcpy.Point(addgeom[0], addgeom[1]))
                                geom = arcpy.Polyline(array)
                                array.removeAll()
                                row[0] = geom
                                cursor.updateRow(row)
                                if addgeom in Connections:
                                    del Connections[addgeom]
                    if Count > 0:
                        arcpy.AddWarning('Joined %s features' % (Count))

            if extend == 'true':
                arcpy.AddMessage(
                    'Extending fracture networks by dangle length')
                arcpy.ExtendLine_edit("in_memory\\templines", dangle,
                                      "FEATURE")

            if short == 'true':
                arcpy.AddMessage(
                    'Removing short fracture networks by dangle length')

                Graph = {}  #Store all node connections

                with arcpy.da.SearchCursor("in_memory\\templines",
                                           ['SHAPE@']) as cursor:

                    for row in cursor:
                        try:
                            start = row[0].firstPoint
                            end = row[0].lastPoint
                            branch = [(round(start.X, 4), round(start.Y, 4)),
                                      (round(end.X, 4), round(end.Y, 4))]

                            for b in branch:
                                if b in Graph:  #node count
                                    Graph[b] += 1
                                else:
                                    Graph[b] = 1

                        except Exception, e:
                            arcpy.AddError('%s' % (e))
                            continue
                Count = 0
                with arcpy.da.UpdateCursor("in_memory\\templines",
                                           ['SHAPE@']) as cursor:
                    for row in cursor:
                        Length = row[0].getLength('PLANAR', d[1])

                        start = row[0].firstPoint
                        end = row[0].lastPoint
                        branch = [(round(start.X, 4), round(start.Y, 4)),
                                  (round(end.X, 4), round(end.Y, 4))]
                        C = 0
                        for b in branch:
                            value = Graph[b]
                            C += value
                        if C == 2 and float(d[0]) > Length:
                            Count += 1
                            cursor.deleteRow()
                if Count > 0:
                    arcpy.AddWarning('Deleted %s short features' % (Count))
Exemple #7
0
def IceCliffLocation(workspace,dem,tileDebarea,pixel,skinny,minSlope,n_iterations,L_e,alpha,beta_e,A_min,phi,gamma):
    import sys
    import os
    import arcpy
    from arcpy import env
    from arcpy.sa import Slope, ExtractByMask, Raster, SetNull, Int
    import matplotlib.pyplot as plt
    import numpy as np
    from numpy import array
    from scipy.optimize import curve_fit
    env.overwriteOutput = True

    try:
        import arcinfo
    except:
        sys.exit("ArcInfo license not available")
        arcpy.AddMessage("ArcInfo license not available")
    if arcpy.CheckExtension("spatial") == "Available":
        arcpy.CheckOutExtension("spatial")
    else:
        sys.exit("Spatial Analyst license not available")
        arcpy.AddMessage("Spatial Analyst license not available")
        
    #Parameters that should be stable:
    slopeLimit = 90 # slope detection capped at this value
    
    ## Loop for optimizing slope
    if str(workspace.split("\\")[-1]) == 'Final':
        n = []
        n.append(minSlope)        
    else:
        minSlope = 0
        n = np.arange(minSlope,slopeLimit,(slopeLimit-minSlope)/n_iterations)

    skipIteration = []
    for minSlope in n:
        
        # check for existing iterations if code has previously run but crashed. 
        if arcpy.ListFeatureClasses("*cliffMap*"):
            fcListPrior = arcpy.ListFeatureClasses("*cliffMap*")
            skipIteration = []
            for prior_i in fcListPrior:
                if int(prior_i[14:16]) == int("%02d" % (int(minSlope),)):
                    skipIteration = 1
        if skipIteration == 1:
            continue

        ## Ice Cliff code  
        if skinny == 'false':
            print 'IceCliffLocation script started...'
        if skinny == 'true':
            print 'skinny IceCliffLocation script started...'
            
        # Parameter that probably should be 0
        minProb = 0 # probability associated with minSlope.
        
        arcpy.CopyFeatures_management(tileDebarea, workspace+"\\del_debarea.shp")
        debarea_iteration = workspace+"\\del_debarea.shp"
        arcpy.env.snapRaster = dem
        outExtractSlope = ExtractByMask(dem, debarea_iteration)

        outExtractSlope.save("dem_extract.TIF")
        if int(round(float(str(arcpy.GetRasterProperties_management(dem, "CELLSIZEX"))))) == pixel:
            dem = "dem_extract.TIF"
        else:    
            arcpy.Resample_management("dem_extract.TIF", "dem_extractResample.TIF", pixel, "NEAREST")
            arcpy.env.snapRaster = dem
            print "DEM resampeld from "+str(int(round(float(str(arcpy.GetRasterProperties_management(dem, "CELLSIZEX"))))))+' to '+str(pixel)
            dem = "dem_extractResample.TIF"
        
        # Create slope raster
        outSlope = Slope(dem, "DEGREE", 1)
        outSlope.save("del_slope.TIF")
    
        # Isolate slope values above minSlope 
        outSetNull = SetNull("del_slope.TIF", "del_slope.TIF", "VALUE <= "+ str(minSlope))
        outSetNull.save("del_minSlope.TIF")       
    
        # Exit process if no cliffs exist
        nocliff = arcpy.GetRasterProperties_management(Int("del_minSlope.TIF"), "ALLNODATA")
        if int(str(nocliff)) == 1:
            print "No area with a slope above "+str(minSlope)+"."
        elif float(str(arcpy.GetRasterProperties_management('del_minSlope.TIF',"MAXIMUM"))) - float(str(arcpy.GetRasterProperties_management('del_minSlope.TIF',"MINIMUM"))) == 0:
            print "Only one pixel with a slope above "+str(minSlope)+", iteration skipped."
        else:
            minMean = float(str(arcpy.GetRasterProperties_management("del_minSlope.TIF", "MEAN"))) 
            minSD = float(str(arcpy.GetRasterProperties_management("del_minSlope.TIF", "STD"))) 

            areaSlope = minMean
            
            print 'areaSlope = ' + str(areaSlope)
            
            # Isolate slope values above areaSlope 
            outSetNull = SetNull("del_slope.TIF", "del_slope.TIF", "VALUE <= "+ str(areaSlope))
            outSetNull.save("del_areaSlope.TIF")
            arcpy.env.snapRaster = dem  
                        
            # Exit process if no cliffs exist
            nocliff = arcpy.GetRasterProperties_management(Int("del_areaSlope.TIF"), "ALLNODATA")
            if int(str(nocliff)) == 1:
                print "No area with a slope above "+str(areaSlope)+"."
            elif float(str(arcpy.GetRasterProperties_management("del_areaSlope.TIF","MAXIMUM"))) - float(str(arcpy.GetRasterProperties_management("del_areaSlope.TIF","MINIMUM"))) == 0:
                print "Only one pixel with a slope above "+str(areaSlope)+", iteration skipped."
            else: 
                seedSlope = minMean+minSD 
                print 'seedSlope = ' + str(seedSlope)
                
                # Isolate slope values above areaSlope 
                outSetNull = SetNull("del_slope.TIF", "del_slope.TIF", "VALUE <= "+ str(seedSlope))
                outSetNull.save("del_seedSlope.TIF")

                # Exit process if no cliffs exist
                nocliff = arcpy.GetRasterProperties_management(Int("del_seedSlope.TIF"), "ALLNODATA")
                if int(str(nocliff)) == 1:
                    print "No seed area with a slope above "+str(seedSlope)+"."
                else:                    
                    # to int speeds up computation time
                    outInt = Int("del_areaSlope.TIF")
                    outInt.save("del_minSlopeInt.TIF")
                    outInt = Int("del_seedSlope.TIF")
                    outInt.save("del_seedSlopeInt.TIF")                  
                        
                    arcpy.RasterToPolygon_conversion("del_minSlopeInt.TIF", "del_minCliffSlope.shp", "NO_SIMPLIFY", "VALUE")
                    arcpy.AddField_management("del_minCliffSlope.shp", "value", "SHORT", 1, "", "", "", "", "")
                    arcpy.Dissolve_management("del_minCliffSlope.shp", "del_minCliff_dissolve.shp", "value")
                    arcpy.MultipartToSinglepart_management("del_minCliff_dissolve.shp", "del_minCliff_explode.shp")
                    arcpy.AddField_management("del_minCliff_explode.shp",'Area','FLOAT')
                    rows = arcpy.UpdateCursor("del_minCliff_explode.shp")
                    for row in rows:
                        areacliff = row.shape.area
                        row.Area = areacliff 
                        rows.updateRow(row)
                    del row, rows
                    arcpy.CopyFeatures_management("del_minCliff_explode.shp", "min"+str("%02d" % (minSlope,))+"_CliffArea.shp")
                    
                    # skinny/non-skinny fix for ending iteration. 0 = no skip, 1 = skip
                    skip_iter = 0 
                    
                    # skinny ice cliffs, does not include ice cliff end extension to speed up computations
                    if skinny == 'true':
                        if arcpy.management.GetCount("del_minCliff_explode.shp")[0] == "0":
                            skip_iter = 1
                            print "No area within del_minCliff_explode.shp, skinny iteration skipped."
                        else:
                            # "_FinalCliffShape.shp" and "_cliffArea.shp" are the same if skinny == true
                            arcpy.CopyFeatures_management("del_minCliff_explode.shp", "min"+str("%02d" % (minSlope,))+"area"+str(int(areaSlope))+"_FinalCliffShape.shp")
                            # copy working .shp, used below
                            arcpy.CopyFeatures_management('del_minCliff_explode.shp', 'del_lineAndArea_area.shp')
                            arcpy.CalculateAreas_stats('del_minCliff_explode.shp', 'del_lineAndArea_area.shp')
                            arcpy.MakeFeatureLayer_management('del_lineAndArea_area.shp', 'tempLayer')
                            expression = 'F_AREA <=' + str((pixel**2)*A_min)
                            arcpy.SelectLayerByAttribute_management('tempLayer', 'NEW_SELECTION', expression)
                            arcpy.DeleteFeatures_management('tempLayer')
                            arcpy.Delete_management('tempLayer')

                    if skinny == 'false':    
                        # buffer in/out area to break up attached features
                        arcpy.Buffer_analysis("del_minCliff_explode.shp", "del_extendLineBuffer.shp", (pixel/2)-0.1, "FULL", "ROUND", "NONE")
    
                        # Generate ice cliff centerlines from Voronoi cells
                        if arcpy.management.GetCount("del_extendLineBuffer.shp")[0] == "0":
                            arcpy.CreateFeatureclass_management(workspace, 'del_lineAndArea_area.shp', "POLYGON","del_minCliff_dissolve.shp")
                            skip_iter = 1
                            print "No area within the criteria defined by seed area value "+str(seedSlope)+", iteration stopped before centerlines."
                        else:
                            arcpy.FeatureToLine_management("del_extendLineBuffer.shp","del_line.shp","","ATTRIBUTES")
                            arcpy.Densify_edit("del_line.shp", "","5", "", "")
                            arcpy.FeatureVerticesToPoints_management ("del_line.shp", "del_verti.shp", "ALL")
                            arcpy.CreateThiessenPolygons_analysis("del_verti.shp","del_voronoiCells.shp" ,"ONLY_FID") 
                            arcpy.RepairGeometry_management("del_voronoiCells.shp")
                            
                            #use geodatabase here due to unexpected error: "Invalid Topology [Duplicate segment.]"
                            arcpy.CreateFileGDB_management(workspace, "fGDB.gdb")
                            fgdb = workspace+"\\fGDB.gdb"
                            #arcpy.env.workspace = fgdb
                            arcpy.Clip_analysis(workspace+"\\del_voronoiCells.shp", workspace+"\\del_extendLineBuffer.shp", fgdb+"\\shp","")
                            arcpy.FeatureToLine_management(fgdb+"\\shp", workspace+"\\del_toLine.shp", "", attributes="ATTRIBUTES")
                            arcpy.Delete_management(fgdb)
                            #arcpy.env.workspace = workspace
                            
                            #arcpy.FeatureToLine_management("del_voronoiCellsClip.shp","del_toLine.shp", "", attributes="ATTRIBUTES")
                            arcpy.MakeFeatureLayer_management("del_toLine.shp", "tempLayer", "", "", "")
                            arcpy.SelectLayerByLocation_management("tempLayer", "CROSSED_BY_THE_OUTLINE_OF","del_minCliff_explode.shp","","NEW_SELECTION")
                            arcpy.DeleteFeatures_management("tempLayer")
                            arcpy.Delete_management("tempLayer")
                            arcpy.Intersect_analysis(["del_toLine.shp",'del_minCliff_explode.shp'],"del_lineIntersect.shp")
                            arcpy.Dissolve_management("del_lineIntersect.shp", "del_toLineDis.shp", "", "", "SINGLE_PART", "DISSOLVE_LINES")
                            arcpy.UnsplitLine_management("del_toLineDis.shp","del_unsplit.shp","Id")
                            arcpy.MakeFeatureLayer_management("del_unsplit.shp", "tempLayer2", "", "", "")
                            arcpy.SelectLayerByLocation_management("tempLayer2", "BOUNDARY_TOUCHES","del_minCliff_explode.shp","","NEW_SELECTION")
                            arcpy.DeleteFeatures_management("tempLayer2")
                            arcpy.Delete_management("tempLayer2")
                            arcpy.cartography.SimplifyLine("del_unsplit.shp","del_clineSimpExp.shp","POINT_REMOVE",10)
                            arcpy.AddField_management("del_clineSimpExp.shp", "value", "SHORT", 1, "", "", "", "", "")
                            arcpy.Dissolve_management("del_clineSimpExp.shp", "del_clineSimp.shp", "value")
                            arcpy.TrimLine_edit("del_clineSimp.shp", "8 meters", "KEEP_SHORT")
                            arcpy.CopyFeatures_management("del_unsplit.shp", "min"+str("%02d" % (minSlope,))+"_Centerlines.shp")
                            
                            #refine centerline for final map
                            if arcpy.management.GetCount("del_clineSimp.shp")[0] == "0":
                                arcpy.CreateFeatureclass_management(workspace, 'del_lineAndArea_area.shp', "POLYGON","del_minCliff_dissolve.shp")
                                skip_iter = 1
                                print "No area big enough to generate a centerline, iteration skipped."
                            else:                        
                            
                                # extend lines to capture cliff ends
                                count = 0
                                print "Extend line started..."
                                
                                jlist = [(pixel/2)-0.1] * int(round(L_e/(pixel/2)))
                                for j in jlist:
                                    #create buffer out to set the limit a line will be extended to
                                    arcpy.Buffer_analysis("del_clineSimp.shp", "del_clineSimpBuff1.shp", j, "FULL", "ROUND", "ALL")
                                    arcpy.PolygonToLine_management("del_clineSimpBuff1.shp","del_clineSimpBuff1line.shp")
                                    #merge centerline and bufferline
                                    arcpy.Merge_management(["del_clineSimp.shp","del_clineSimpBuff1line.shp"], "del_clineSimpBuff1merge_dis.shp")
                                    arcpy.Delete_management("del_clineSimp.shp")
                                    print "Extend line "+str(count)+" started..."
                                    arcpy.MultipartToSinglepart_management("del_clineSimpBuff1merge_dis.shp", "del_clineSimpBuff1merge.shp")
                                    arcpy.MakeFeatureLayer_management("del_clineSimpBuff1merge.shp", "lineLayer", "", "", "")
                                    arcpy.SelectLayerByLocation_management("lineLayer", "SHARE_A_LINE_SEGMENT_WITH", "del_clineSimpBuff1.shp", "", "NEW_SELECTION", "INVERT")
                                    arcpy.ExtendLine_edit("del_clineSimpBuff1merge.shp", str(j+1)+" meters", "EXTENSION")
                                    
                                    #select share a line segment with buffer to remove buffer
                                     
                                    arcpy.SelectLayerByLocation_management("lineLayer", "SHARE_A_LINE_SEGMENT_WITH", "del_clineSimpBuff1.shp", "", "NEW_SELECTION") 
                                    arcpy.DeleteFeatures_management("lineLayer")
                                    arcpy.Delete_management("lineLayer")
                                    arcpy.CopyFeatures_management("del_clineSimpBuff1merge.shp", "del_clineSimp.shp")
                                    arcpy.Delete_management("del_clineSimpBuff1.shp")
                                    arcpy.Delete_management("del_clineSimpBuff1line.shp")
                                    arcpy.Delete_management("del_clineSimpBuff1merge.shp")
                                    count = count + j                                
                                del j, jlist
        
                                #remove last short ribs with a lenght threhold then reattach centerlines that may have been split
                                # calculate lenght of each centerline
                                if arcpy.management.GetCount("del_clineSimp.shp")[0] == "0":
                                    arcpy.CreateFeatureclass_management(workspace, 'del_lineAndArea_area.shp', "POLYGON","del_minCliff_explode.shp")
                                    skip_iter = 1
                                    print "Centerline shape empty, iteration skipped."
                                else:
                                    arcpy.AddField_management("del_clineSimp.shp",'L','FLOAT')
                                    rows = arcpy.UpdateCursor("del_clineSimp.shp")
                                    for row in rows:
                                        areacliff = row.shape.length
                                        row.L = areacliff 
                                        rows.updateRow(row)
                                    del row, rows
                                    arcpy.CopyFeatures_management("del_clineSimp.shp", "min"+str("%02d" % (minSlope,))+"_extendedCenterlines.shp")
                                    
                                    # buffer out centerlines to capture end area removed in earlier buffer
                                    arcpy.Buffer_analysis("del_clineSimp.shp", "del_CliffCenterlineOut.shp", ((alpha*pixel*(2**(1/2)))/2), "FULL", "ROUND", "NONE")
            
                                    # define area with a slope less than that which defined "del_minCliff_dissolve.shp"
                                    edgeAreaSlope = areaSlope-beta_e
                                    print "Edge area defined by slope "+str(edgeAreaSlope)
                                    outSetNull = SetNull("del_slope.TIF", "del_slope.TIF", "VALUE <= "+ str(edgeAreaSlope))
                                    outSetNull.save("del_edgeSlope.TIF") 
                                   
                                    outInt = Int("del_edgeSlope.TIF")
                                    outInt.save("del_edgeSlopeInt.TIF")                    
                                    arcpy.RasterToPolygon_conversion("del_edgeSlopeInt.TIF", "del_edgeAreaSlope.shp", "NO_SIMPLIFY", "VALUE")
                                    arcpy.AddField_management("del_edgeAreaSlope.shp", "value", "SHORT", 1, "", "", "", "", "")
                                    arcpy.Dissolve_management("del_edgeAreaSlope.shp", "del_edgeAreaSlope_dissolve.shp", "value")
                                    arcpy.CopyFeatures_management("del_edgeAreaSlope_dissolve.shp", "min"+str("%02d" % (minSlope,))+"_edgeArea.shp")
                                    arcpy.Intersect_analysis (["del_edgeAreaSlope_dissolve.shp", "del_CliffCenterlineOut.shp"], "del_betaF_edgeArea.shp")
                        
                                    # merge buffered lines with buffered area                    
                                    arcpy.Merge_management(["del_betaF_edgeArea.shp", "del_minCliff_explode.shp"], "del_lineAndArea.shp")
                                    arcpy.AddField_management("del_lineAndArea.shp", "valueDis", "SHORT", 1, "", "", "", "", "")                    
                                    arcpy.Dissolve_management("del_lineAndArea.shp", "del_lineAndArea_dissolve1.shp", "valueDis")
                                    arcpy.RepairGeometry_management("del_lineAndArea_dissolve1.shp")
                                    # fill holes and remove shapes less than one pixel to avoid error from buffer tool
                                    arcpy.MultipartToSinglepart_management("del_lineAndArea_dissolve1.shp", "del_lineAndArea_explode1.shp")
                                    arcpy.CalculateAreas_stats("del_lineAndArea_explode1.shp", 'del_lineAndArea_area1.shp')
                                    arcpy.MakeFeatureLayer_management('del_lineAndArea_area1.shp', 'tempLayer')
                                    expression = 'F_AREA <' + str(pixel**2) # m2
                                    arcpy.SelectLayerByAttribute_management('tempLayer', 'NEW_SELECTION', expression)
                                    arcpy.DeleteFeatures_management('tempLayer')
                                    arcpy.Delete_management('tempLayer')
                                    arcpy.cartography.AggregatePolygons('del_lineAndArea_area1.shp', "del_lineAndArea_dissolve.shp", 1, 0, pixel**2, 'NON_ORTHOGONAL') 
                                                       
                                    arcpy.RepairGeometry_management("del_lineAndArea_dissolve.shp")
                                    # buffer in to reomve sliver geometries and out to make a diagonal set of single pixel shapes one feature
                                    arcpy.Buffer_analysis("del_lineAndArea_dissolve.shp", "del_lineAndArea_dissolveSmallBufferIn.shp", -0.5, "FULL", "ROUND", "ALL")
                                    arcpy.Buffer_analysis("del_lineAndArea_dissolveSmallBufferIn.shp", "del_lineAndArea_dissolveSmallBuffer.shp", 1, "FULL", "ROUND", "ALL")
                                    arcpy.MultipartToSinglepart_management("del_lineAndArea_dissolveSmallBuffer.shp", "del_lineAndArea_explode.shp")
                                    arcpy.CalculateAreas_stats('del_lineAndArea_explode.shp', 'del_lineAndArea_area.shp')
                                    arcpy.MakeFeatureLayer_management('del_lineAndArea_area.shp', 'tempLayer')
                                    expression = 'F_AREA <=' + str((pixel**2)*A_min)
                                    arcpy.SelectLayerByAttribute_management('tempLayer', 'NEW_SELECTION', expression)
                                    arcpy.DeleteFeatures_management('tempLayer')
                                    arcpy.Delete_management('tempLayer')
                                    
                                    if arcpy.management.GetCount("del_lineAndArea_area.shp")[0] == "0":
                                        print "del_lineAndArea_area.shp empty, iteration stopped."
                                        skip_iter = 1
                                    else:
                                        arcpy.AddField_management("del_lineAndArea_area.shp", "value", "SHORT", 1, "", "", "", "", "")
                                        arcpy.CopyFeatures_management('del_lineAndArea_area.shp', "min"+str("%02d" % (minSlope,))+"area"+str(int(areaSlope))+"_FinalCliffShape.shp")                         
                    if skip_iter == 0:
                        # CDF for values between minSlope and maxSlope
                        outSetNull = SetNull("del_slope.TIF", "del_slope.TIF", "VALUE >= "+ str(minSlope))
                        outSetNull.save("del_min.TIF")
                        arcpy.RasterToFloat_conversion("del_min.TIF", "del_min.flt")
                        minsl = Raster('del_min.flt')
                        slopemin = minsl*0.0
                        slopemin.save('del_minSl.TIF')            
                            
                        outSetNull = SetNull("del_slope.TIF", "del_slope.TIF", "VALUE > "+ str(seedSlope))
                        outSetNull = SetNull(outSetNull, outSetNull, "VALUE < "+ str(minSlope))
                        outSetNull.save("del_mid.TIF")
                        arcpy.RasterToFloat_conversion("del_mid.TIF", "del_mid.flt")
                        midsl = Raster('del_mid.flt')
                        b = (1-(((1-minProb)/(seedSlope-minSlope))*seedSlope))
                        slopemid = (((1-minProb)/(seedSlope-minSlope))*midsl)+b
                        arcpy.env.snapRaster = dem
                        slopemid.save('del_midSl.TIF')
                        arcpy.env.snapRaster = dem
        
                        outSetNull = SetNull("del_slope.TIF", "del_slope.TIF", "VALUE <= "+ str(seedSlope))
                        outSetNull.save("del_max.TIF")
                        arcpy.RasterToFloat_conversion("del_max.TIF", "del_max.flt")
                        maxsl = Raster('del_max.flt')
                        slopemax = maxsl*0.0+1.0
                        arcpy.env.snapRaster = dem
                        slopemax.save('del_maxSl.TIF')
                        arcpy.env.snapRaster = dem
                                
                        arcpy.MosaicToNewRaster_management("del_minSl.TIF;del_midSl.TIF;del_maxSl.TIF", workspace, "del_cliffProbabilitySlope.TIF", "", "32_BIT_FLOAT", "", "1", "LAST","FIRST")
                        arcpy.env.snapRaster = dem
        
                        # extract cliff probability and apply reduction factor to area outside of buffer.shp
                        if arcpy.management.GetCount("del_lineAndArea_area.shp")[0] == "0":
                            print "del_lineAndArea_area.shp is empty, did not create: CliffProbability_betai" + str("%02d" % (int(minSlope),)) + "betaA"  + str(int(areaSlope))+".TIF"
                        else:  
                            outExtractSlope = ExtractByMask("del_cliffProbabilitySlope.TIF", "del_lineAndArea_area.shp")
                            outExtractSlope.save("del_final_cliffs_found.TIF")
                            
                            arcpy.RasterToFloat_conversion("del_cliffProbabilitySlope.TIF", "del_CliffProbabilitySlope.flt")
                            CliffProbabilitySlope = Raster('del_CliffProbabilitySlope.flt')
                            CliffProbabilitySlopeREDUCED = CliffProbabilitySlope*phi
                            arcpy.env.snapRaster = dem
                            CliffProbabilitySlopeREDUCED.save('del_CliffProbabilitySlopeREDUCED.TIF')
            
                            arcpy.MosaicToNewRaster_management("del_final_cliffs_found.TIF;del_CliffProbabilitySlopeREDUCED.TIF", workspace, "CliffProbability_betai" + str("%02d" % (int(minSlope),)) + "betaA"  + str(int(areaSlope))+".TIF", "", "32_BIT_FLOAT", "", "1", "FIRST","FIRST")
                            arcpy.env.snapRaster = dem
                            
                            del CliffProbabilitySlope
                            del CliffProbabilitySlopeREDUCED
                                                       
                        del minsl
                        del midsl
                        del maxsl


                ## ----------------------------------
                ## Compute percent cliff in total spatial domain

                cliff_area_sum = 0
                debris_area_sum = 0
                Perc_Cliff = 0
                arcpy.CalculateAreas_stats(debarea_iteration, 'del_debris_area.shp')
                with arcpy.da.SearchCursor('del_debris_area.shp', ['F_AREA']) as cursor:
                    for row in cursor:
                        debris_area_sum += row[0]                
                                
                if os.path.isfile(workspace+'\\del_lineAndArea_area.shp') == False:
                    print "'del_lineAndArea_area.shp'does not exist."
                elif arcpy.management.GetCount('del_lineAndArea_area.shp')[0] == "0":
                    print "No area within 'del_lineAndArea_area.shp'."
                else:
                    with arcpy.da.SearchCursor('del_lineAndArea_area.shp', ['F_AREA']) as cursor:
                        for row in cursor:
                            cliff_area_sum += row[0]
                    Perc_Cliff = (cliff_area_sum/debris_area_sum)*100
                    arcpy.Dissolve_management("del_lineAndArea_area.shp", 'cliffMap_betai' + str("%02d" % (int(minSlope),)) + 'betaA' + str(int(areaSlope)) + '.shp', "value")
                    arcpy.AddField_management('cliffMap_betai' + str("%02d" % (int(minSlope),)) + 'betaA' + str(int(areaSlope)) + '.shp','minSlope','FLOAT')
                    arcpy.AddField_management('cliffMap_betai' + str("%02d" % (int(minSlope),)) + 'betaA' + str(int(areaSlope)) + '.shp','Area_Cliff','FLOAT')
                    arcpy.AddField_management('cliffMap_betai' + str("%02d" % (int(minSlope),)) + 'betaA' + str(int(areaSlope)) + '.shp','Area_Deb','FLOAT')
                    
                    arcpy.AddField_management('cliffMap_betai' + str("%02d" % (int(minSlope),)) + 'betaA' + str(int(areaSlope)) + '.shp','Perc_Cliff','FLOAT')
                    rows = arcpy.UpdateCursor('cliffMap_betai' + str("%02d" % (int(minSlope),)) + 'betaA' + str(int(areaSlope)) + '.shp')
                    for row in rows:
                        row.setValue('Area_Cliff', cliff_area_sum)
                        row.setValue('Area_Deb', debris_area_sum)
                        row.setValue('minSlope', minSlope)
                        row.setValue('Perc_Cliff', Perc_Cliff)
                        rows.updateRow(row)
                    del row, rows
                                     
                    print 'IceCliffLocation script [minSlope: ' + str("%02d" % (int(minSlope),)) + ' areaSlope: ' + str(int(areaSlope))+ '] done...'
                                         
        rasterList = arcpy.ListRasters("*del*")
        for raster in rasterList:
            arcpy.Delete_management(raster)
        del raster
        del rasterList

        fcList = arcpy.ListFeatureClasses("*del*")
        for fc in fcList:
            arcpy.Delete_management(fc)
        del fc
        del fcList

        print "intermediate files deleted"
            
    del minSlope
    del n
    
    if str(workspace.split("\\")[-1]) == 'Final':
        print "Script complete"        
    else:
        initialSlope_doubles = []
        percentCliffs_doubles = []
        initialSlope = []
        percentCliffs = []
        xfit = []
        yfit = []
        fcList = []
        arr = []
        fcList = arcpy.ListFeatureClasses("*cliffMap*")
        arcpy.Merge_management(fcList, "mergedSolutions.shp")
        arr = arcpy.da.TableToNumPyArray("mergedSolutions.shp", ('Perc_Cliff','minSlope'))
        arcpy.Delete_management("del_mergedSolutions.shp")
        initialSlope_doubles = [row[1] for row in arr]
        percentCliffs_doubles = [row[0] for row in arr]
        
        #remove rows that are repeated due to (possible) earlier tiled dissolve from insufficient memory 
        for i,j in enumerate(initialSlope_doubles):
            if j != initialSlope_doubles[(i-1) % len(initialSlope_doubles)]:
                initialSlope.append(j)
        del i,j
        for i,j in enumerate(percentCliffs_doubles):
            if j != percentCliffs_doubles[(i-1) % len(percentCliffs_doubles)]:
                percentCliffs.append(j)
        del i,j
                
        def func(x,a,b,c):
            return a*np.exp(-((x-b)/c)**2)
        try:
            popt, pcov = curve_fit(func,initialSlope,percentCliffs, maxfev=1000)
        except RuntimeError:
            fig = plt.figure()
            ax1 = fig.add_subplot(111)
            ax1.plot(initialSlope, percentCliffs, 'ko');plt.draw()
            fig.show()            
            print("Error - curve_fit failed")
        xfit = np.linspace(min(initialSlope), max(initialSlope), 100)
        yfit = popt[0]*np.exp(-((xfit-popt[1])/popt[2])**2)
        
        def secondDer(x):
            return popt[0]*(((4*(x-popt[1])**2*np.exp(-(x-popt[1])**2/popt[2]**2))/popt[2]**4)-((2*np.exp(-(x-popt[1])**2/popt[2]**2))/popt[2]**2))
        a1 = []
        a1 = [i for i in xrange(91)]
        a2 = secondDer(a1)
        #the next 3 for loops and a[x] variables define 1 of the 2 points to derive the optimization line.
        a3 = []
        a4 = []
        # values of second derivative where slope is below 'gamma'
        for i, j in enumerate(a2):
            if j <= gamma:
                a3.append(i) == i
        # find the steepest point (in the middle of the side of the bell)
        for i, j in enumerate(a2):
            if j == max(a2):
                m=i
        # take only values to the right of 'm' in case the curve is flat at 0 slope
        for i in a3:
            if i > m:
                a4.append(i) == i
        del i,j
                
        ax = min(a4) 
        ay = popt[0]*np.exp(-((ax-popt[1])/popt[2])**2)
        
        #find max of bell for first point in optmization line
        yfit_array = array(yfit)        
        ftup = (np.where(yfit_array == max(yfit_array)))
        f = int(ftup[0]) # x,y index of max yfit 
                
        # d = distance from fit Equation 2 (Herreid and Pellicciotti, 2018) to line definded by ((xfit[0],yfit[0]),(ax,yx))
        d = abs((yfit[f]-ay)*xfit-(xfit[f]-ax)*yfit+xfit[f]*ay-yfit[f]*ax)/((yfit[f]-ay)**2+(xfit[f]-ax)**2)**(1/2)
        # crit is the index of the longest d
        crit = np.where(d == max(d))
        m = (yfit[f]-ay)/(xfit[f]-ax)
        b = yfit[f]-m*xfit[f]
        x_crit = (xfit[crit]+m*yfit[crit]-m*b)/(m**2+1)
        y_crit = m*((xfit[crit]+m*yfit[crit]-m*b)/(m**2+1))+b
        
        fig = plt.figure()
        ax1 = fig.add_subplot(111)
        ax1.plot(initialSlope, percentCliffs, 'ko'); plt.plot([xfit[f],ax],[yfit[f],ay]); plt.plot([xfit[crit],x_crit],[yfit[crit],y_crit]); plt.plot(xfit,yfit);plt.xlim(0, 100);plt.ylim(0, 100);plt.gca().set_aspect('equal', adjustable='box');plt.draw()
        ax1.set_xlabel(r'$\mathrm{\beta_i (^\circ)}$')
        ax1.set_ylabel('Ice cliff fraction (%)')
        fig.show()
        #fig.canvas.flush_events()
        import time
        time.sleep(1)
        #plt.pause(0.01)
        #plt.waitforbuttonpress()
        
        #save data used to make figure
        np.save(workspace+'\\figureData', (initialSlope, percentCliffs,[xfit[f],ax],[yfit[f],ay],[xfit[crit],x_crit],[yfit[crit],y_crit],xfit,yfit))

        IceCliffLocation.minSlope = float(xfit[crit])
Exemple #8
0
def trim_dangles(fc):
    with arcpy.da.Editor(workspace) as edit:
        ##    arcpy.env.extent = arcpy.Describe(fc).extent
        arcpy.TrimLine_edit(fc, '10 Feet', 'DELETE_SHORT')