Ejemplo n.º 1
0
def main():
    #  import required modules and extensions
    import arcpy
    arcpy.CheckOutExtension('Spatial')

    #  environment settings
    arcpy.env.workspace = 'in_memory' # set workspace to temporary workspace
    arcpy.env.overwriteOutput = True  # set to overwrite output
    sr = arcpy.Describe(flowline_path).spatialReference

    #  dissolve input flowline network
    flowline_dissolve = arcpy.Dissolve_management(flowline_path, 'in_memory/flowline_dissolve', '', '', 'SINGLE_PART', 'UNSPLIT_LINES')

    #  create line id field and line length fields
    arcpy.AddField_management(flowline_dissolve, 'LineID', 'SHORT')
    arcpy.AddField_management(flowline_dissolve, 'LineLen', 'DOUBLE')
    with arcpy.da.UpdateCursor(flowline_dissolve, ['FID', 'LineID', 'Shape@Length', 'LineLen']) as cursor:
        for row in cursor:
            row[1] = row[0]
            row[3] = row[2]
            cursor.updateRow(row)

    #  flip lines so segment points are created from end-start of line rather than start-end
    arcpy.FlipLine_edit(flowline_dissolve)

    #  create points at regular interval along each flowline
    seg_pts = arcpy.CreateFeatureclass_management('in_memory', 'seg_pts', 'POINT', '', 'DISABLED', 'DISABLED', sr)
    with arcpy.da.SearchCursor(flowline_dissolve, ['SHAPE@'], spatial_reference = sr) as search:
        with arcpy.da.InsertCursor(seg_pts, ['SHAPE@']) as insert:
            for row in search:
                try:
                    lineGeom = row[0]
                    lineLength = row[0].length
                    lineDist = interval
                    while lineDist + min_segLength <= lineLength:
                        newPoint = lineGeom.positionAlongLine(lineDist)
                        insert.insertRow(newPoint)
                        lineDist += interval
                except Exception as e:
                    arcpy.AddMessage(str(e.message))

    # split flowlines at segment interval points
    flowline_seg = arcpy.SplitLineAtPoint_management(flowline_dissolve, seg_pts, 'in_memory/flowline_seg', 1.0)

    # add and populate segment id and length fields
    arcpy.AddField_management(flowline_seg, 'SegID', 'SHORT')
    arcpy.AddField_management(flowline_seg, 'SegLen', 'DOUBLE')
    with arcpy.da.UpdateCursor(flowline_seg, ['FID', 'SegID', 'Shape@Length', 'SegLen']) as cursor:
        for row in cursor:
            row[1] = row[0]
            row[3] = row[2]
            cursor.updateRow(row)

    #  flip lines back to correct direction
    arcpy.FlipLine_edit(flowline_seg)

    # save flowline segment output
    arcpy.CopyFeatures_management(flowline_seg, outpath)

    arcpy.Delete_management('in_memory')
def routeFlipTemp(routesMZ, idField, refPointLayer):
    flipRtField = "FlipRt"
    arcpy.AddField_management(routesMZ, flipRtField, "SHORT")
    routesCursor = arcpy.UpdateCursor(routesMZ)
    
    for route in routesCursor:
        rtShp = route.getValue(inFcShpField)
        rtID = route.getValue(idField)
        print rtID
        rtEndPnt = rtShp.lastPoint
        #TODO if no ref points are found script errors out
        refPntCursor = arcpy.SearchCursor(refPointLayer, """ "LABEL" = '""" + rtID + "'")#Create reference point cursor limited by route ID of current route
        #Get the first ref point of the route and reset the closest point with it.
        #
        p = refPntCursor.next()
        closestRefPnt = p.getValue(inFcShpField).centroid
        closestDist = distanceFormula(rtEndPnt.X, rtEndPnt.Y, closestRefPnt.X, closestRefPnt.Y)   
        print "SP : " + str(p.CALPT_TYPE) + str(closestDist)
        closestType = str(p.CALPT_TYPE)
        ##
        for refPnt in refPntCursor:
            nextRefPnt = refPnt.getValue(inFcShpField).centroid
            nextDist = distanceFormula(rtEndPnt.X, rtEndPnt.Y, nextRefPnt.X, nextRefPnt.Y)
    
            if nextDist < closestDist:
                closestRefPnt = refPnt
                closestDist = nextDist
                closestType = str(refPnt.CALPT_TYPE)
                print str(refPnt.CALPT_TYPE) + " c: " + str(closestDist)
                
            elif nextDist == closestDist:
                if str(refPnt.CALPT_TYPE).count("END") > 0 or str(refPnt.CALPT_TYPE).count("START") > 0:
                    closestRefPnt = refPnt
                    closestDist = nextDist
                    closestType = str(refPnt.CALPT_TYPE)
                    print str(refPnt.CALPT_TYPE) + " c: " + str(closestDist)
                
#            else:
#                print str(refPnt.CALPT_TYPE) + " f: " + str(nextDist)
        
        print  closestType + " final: " + str(closestDist) 
        print
        if closestType.count("START") > 0: 
            route.setValue(flipRtField, 1)
            routesCursor.updateRow(route)

    del route
    del routesCursor 
    #Select by the flipRtField to flip routes that need it.
    arcpy.MakeFeatureLayer_management(routesMZ, "flipRts", '"' + flipRtField + '"' + " = 1 ")
    matchCount = int(arcpy.GetCount_management("flipRts").getOutput(0)) #temp
    arcpy.AddMessage("Attemping Flip of: " + str(matchCount))  
    arcpy.FlipLine_edit("flipRts")
    arcpy.AddMessage("Routes flipped: " + str(matchCount))
    def onClick(self):
        # Script to flip attributes on a centerline.
        # arcpy.da.SearchCursor requires ArcGIS 10.1 or higher
        # coding help via GIS StackExchange:
        # http://gis.stackexchange.com/a/79625/15499
        # http://gis.stackexchange.com/questions/79615/is-there-a-programmatic-way-to-swap-attributes-on-a-feature/79625?noredirect=1#comment109573_79625

        try:
            workspace = r"Database Connections\facilities@5160_93.sde"  # set workspace to SDE connection
            fields = ([
                "FROMLEFTP", "TORIGHTP", "TOLEFTP", "FROMRIGHTP", "FROMLEFTA",
                "TORIGHTA", "TOLEFTA", "FROMRIGHTA", "TRAFFIC_FLOW"
            ])  # set the fields to the ones being flipped
            fc = "FACILITIES.Centerline"  # set the feature class to the SDE feature class name
            fc_shp = "CENTERLINE_FLIPS"  # feature class to calculate
            field = "FLIP"  # calc filed to change
            fc_desc = arcpy.Describe(fc)  # describe selection of fc_shape
            fc_shp_desc = arcpy.Describe(
                fc_shp)  # describe selection of fc_shape

            if not fc_desc.FIDSet == '' and fc_shp_desc == '':  # an fc_shp is selected
                # Marked the discrepancy as done in the CENTERLINE_FLIPS tracking shapefile
                arcpy.CalculateField_management(fc_shp, field, '1')

                # loops through selected rows and swaps the values
                with arcpy.da.UpdateCursor(fc, fields) as cursor:
                    for row in cursor:
                        # flips the line direction
                        arcpy.FlipLine_edit("FACILITIES.Centerline")

                        # update swaps
                        row[0], row[1] = row[1], row[0]
                        row[2], row[3] = row[3], row[2]
                        row[4], row[5] = row[5], row[4]
                        row[6], row[7] = row[7], row[6]

                        # swap directions
                        if row[8] == 'F':
                            row[8] = 'R'
                            cursor.updateRow(row)
                        elif row[8] == 'R':
                            row[8] = 'F'
                            cursor.updateRow(row)
                        else:
                            cursor.updateRow(row)

            else:
                # this is not working at the moment
                arcpy.AddError(
                    "Error. No {0} features are selected.".format(fc_shp))
                print(arcpy.GetMessages())
        except Exception as e:
            arcpy.AddError(e.message)
Ejemplo n.º 4
0
    def generate_linkshape(arcs, output_dir):
        linkshape = os.path.join(output_dir, 'highway.linkshape')
        w = open(linkshape, 'w')
        w.write('c HIGHWAY LINK SHAPE FILE FOR SCENARIO {0}\n'.format(scen))
        w.write('c {0}\n'.format(MHN.timestamp('%d%b%y').upper()))
        w.write('t linkvertices\n')

        def write_vertices(fc, writer, reversed=False):
            with arcpy.da.SearchCursor(fc,
                                       ['SHAPE@', 'ANODE', 'BNODE']) as cursor:
                for row in cursor:
                    arc = row[0]
                    if not reversed:
                        fnode = str(row[1])
                        tnode = str(row[2])
                    else:
                        fnode = str(row[2])  # ANODE now references to-node
                        tnode = str(row[1])  # BNODE now references from-node
                    writer.write(' '.join(['r', fnode, tnode]) + '\n')
                    n = 0  # Before for-loop, will not be reset if an arc is multi-part for some reason
                    for part in arc:
                        vertex = part.next()
                        while vertex:
                            n += 1
                            writer.write(' '.join([
                                'a', fnode, tnode,
                                str(n),
                                str(vertex.X),
                                str(vertex.Y)
                            ]) + '\n')
                            vertex = part.next()
                            if not vertex:
                                vertex = part.next()
            return None

        arcs_mem = os.path.join(MHN.mem, 'arcs')
        arcpy.CopyFeatures_management(arcs, arcs_mem)
        write_vertices(arcs_mem, w)

        arcs_mem_flipped = os.path.join(MHN.mem, 'arcs_flipped')
        arcs_2dir_lyr = 'arcs_2dir'
        arcpy.MakeFeatureLayer_management(arcs_mem, arcs_2dir_lyr,
                                          ''' "DIRECTIONS" <> '1' ''')
        arcpy.CopyFeatures_management(arcs_2dir_lyr, arcs_mem_flipped)
        arcpy.FlipLine_edit(arcs_mem_flipped)
        write_vertices(arcs_mem_flipped, w, reversed=True)

        w.close()
        arcpy.Delete_management(arcs_mem)
        arcpy.Delete_management(arcs_mem_flipped)
        return linkshape
Ejemplo n.º 5
0
    def correct_orientation(self, geometry_name, geometry_folder, networkLine):
        arcpy.env.overwriteOutput = True

        print("Création du fichier du réseau avec le bon sens d'écoulement")
        arcpy.gp.TraceGeometricNetwork(
            geometry_folder + geometry_name, "lyr",
            geometry_folder + networkLine + "_Exutoire", "TRACE_UPSTREAM")

        arcpy.CopyFeatures_management(
            "lyr/" + networkLine, geometry_folder + networkLine + "_Upstream")

        print(
            "Création du fichier des réseaux avec le mauvais sens d'écoulement"
        )
        arcpy.SelectLayerByAttribute_management("lyr/" + networkLine,
                                                "SWITCH_SELECTION")
        arcpy.CopyFeatures_management(
            "lyr/" + networkLine,
            geometry_folder + networkLine + "_notUpstream")
        arcpy.SelectLayerByAttribute_management('lyr/' + networkLine,
                                                "CLEAR_SELECTION")
        arcpy.SelectLayerByAttribute_management(
            'lyr/' + networkLine + "_summit", "CLEAR_SELECTION")
        arcpy.Delete_management("lyr")

        print(
            "Sélection des entités avec un mauvais sens de digitalisation et qui ne sont pas intermitent"
        )
        arcpy.MakeFeatureLayer_management(
            geometry_folder + networkLine + "_notUpstream", 'lyr')
        arcpy.SelectLayerByLocation_management(
            'lyr', "BOUNDARY_TOUCHES",
            geometry_folder + networkLine + "_Upstream", "#", "NEW_SELECTION")

        #arcpy.SelectLayerByAttribute_management('lyr',"SUBSET_SELECTION",flowField + " = '" + flowAttribut + "'")

        print("Correction du sens de digitalisation")
        arcpy.FlipLine_edit('lyr')
        arcpy.SelectLayerByAttribute_management('lyr', "CLEAR_SELECTION")
        # arcpy.Delete_management("lyr")

        print("Assemblage des données du nouveau réseau")
        arcpy.Delete_management(geometry_folder + "/" + geometry_name)
        arcpy.Delete_management(geometry_folder + networkLine)
        arcpy.Merge_management(
            geometry_folder + networkLine + "_Upstream;" + geometry_folder +
            networkLine + "_notUpstream", geometry_folder + networkLine)
def line_extend_within_polygon(boundary_polygon, lines_to_extend):
    """
	This python function can extend the lines within a boundary polygon upto the border line. 
	Here, boundary_polygon is the polygon shapefile and the lines_to_extend is the line shapefile which will be extended upto the border using the function.
	"""
    arcpy.PolygonToLine_management(in_features=boundary_polygon,
                                   out_feature_class="boundary_line",
                                   neighbor_option="IDENTIFY_NEIGHBORS")
    arcpy.RepairGeometry_management(in_features=lines_to_extend,
                                    delete_null="DELETE_NULL")

    coastline = "boundary_line"
    directions = lines_to_extend
    g = arcpy.Geometry()
    bank = arcpy.CopyFeatures_management(coastline, g)[0]

    for i in range(2):
        with arcpy.da.UpdateCursor(directions, "Shape@") as cursor:
            for row in cursor:
                line = row[0]
                pStart = line.firstPoint
                pEnd = line.lastPoint
                L = line.length
                dX = (pEnd.X - pStart.X) / L
                dY = (pEnd.Y - pStart.Y) / L
                p = pEnd
                m = 0
                while True:
                    l = bank.distanceTo(p)
                    L += l
                    p.X = pStart.X + dX * L
                    p.Y = pStart.Y + dY * L
                    m += 1
                    if m > 100: break
                    if l < 0.001: break
                if m > 100: continue
                row[0] = arcpy.Polyline(arcpy.Array([pStart, p]))
                cursor.updateRow(row)
        if i == 0:
            arcpy.FlipLine_edit(in_features=directions)

    # deleting the boundary_line layer
    arcpy.Delete_management(coastline)
    return
Ejemplo n.º 7
0
    outlines.append(
        arcpy.Polyline(arcpy.Array([start.centroid, end.centroid]), sr))
    outlines.append(
        arcpy.Polyline(arcpy.Array([start.centroid, end2.centroid]), sr))
    arcpy.CopyFeatures_management(outlines, 'in_memory\Aux1')
del cursor1

# Define cursor to loop the Plan Profile Line Feature Layer
cursor2 = arcpy.SearchCursor(profileFC)

# Adjust the value in case the azimuth is greater than 180
for row in cursor2:
    azVal = row.BEARING
    if azVal > 180:
        azVal = azVal - 180
        arcpy.FlipLine_edit(profileFC)
    arcpy.AddMessage("Bearing azimuth profile line: " + str(azVal))
    arcpy.CalculateField_management(profileFC, "BEARING", str(azVal), "PYTHON",
                                    "#")

arcpy.SpatialJoin_analysis(
    'in_memory\Aux1', strDataFC, 'in_memory\Aux2'
)  # Join the Structural Data attributes to the temporal projection lines
arcpy.Intersect_analysis(
    [profileFC, 'in_memory\Aux2'], 'in_memory\Aux5', "ALL", "", "POINT"
)  # Capture the intersection points to project the structural data in the plan profile line

# Project the intersection points in case there are faults and/or folds

if foldFC != '' and faultFC != '':
    arcpy.Intersect_analysis([profileFC, foldFC], 'in_memory\Aux3', "ALL", "",
Ejemplo n.º 8
0
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
    def _stream_direction(self, stream):
        """
        Compute elevation of start/end point of stream parts.
        Add code of ascending stream part into attribute table.
        
        :param stream: vector stream features
        """
        # TODO: vyresit mazani atributu v atributove tabulce (jestli je to potreba)
        # TODO: vyresit nasledujici:
        #
        # Nasledujici blok je redundantni, nicmene do "stream"
        # pridava nekolik sloupecku, u kterych jsem nemohl dohledat,
        # jestli se s nimi neco dela. Proto to tu zatim nechavam.

        #        start = arcpy.FeatureVerticesToPoints_management(
        #            stream, os.path.join(self.temp, self._data["start"]), "START"
        #        )

        #        end = arcpy.FeatureVerticesToPoints_management(
        #            stream, os.path.join(self.temp, self._data["end"]), "END"
        #        )

        start = arcpy.FeatureVerticesToPoints_management(
            stream, self.storage.output_filepath("start"), "START")

        end = arcpy.FeatureVerticesToPoints_management(
            stream, self.storage.output_filepath("end"), "END")
        arcpy.sa.ExtractMultiValuesToPoints(
            start, [[self.dem_clip, self._data["start_elev"]]], "NONE")
        arcpy.sa.ExtractMultiValuesToPoints(
            end, [[self.dem_clip, self._data["end_elev"]]], "NONE")

        # Join
        self._join_table(stream, self._primary_key, start, "ORIG_FID")
        self._join_table(stream, self._primary_key, end, "ORIG_FID")

        self._delete_fields(stream, [
            "SHAPE_LEN", "SHAPE_LENG", "SHAPE_LE_1", "NAZ_TOK_1", "TOK_ID_1",
            "SHAPE_LE_2", "SHAPE_LE_3", "NAZ_TOK_12", "TOK_ID_12",
            "SHAPE_LE_4", "ORIG_FID_1"
        ])
        self._delete_fields(
            stream, ["start_elev", "end_elev", "ORIG_FID", "ORIG_FID_1"])

        start = arcpy.FeatureVerticesToPoints_management(
            stream, self.storage.output_filepath("start"), "START")

        end = arcpy.FeatureVerticesToPoints_management(
            stream, self.storage.output_filepath("end"), "END")

        arcpy.sa.ExtractMultiValuesToPoints(start,
                                            [[self.dem_clip, "start_elev"]],
                                            "NONE")
        arcpy.sa.ExtractMultiValuesToPoints(end, [[self.dem_clip, "end_elev"]],
                                            "NONE")
        arcpy.AddXY_management(start)
        arcpy.AddXY_management(end)

        # Join
        self._join_table(stream, self._primary_key, start, "ORIG_FID")
        self._join_table(stream, self._primary_key, end, "ORIG_FID")

        self._delete_fields(
            stream, ["NAZ_TOK_1", "NAZ_TOK_12", "TOK_ID_1", "TOK_ID_12"])

        field = [
            self._primary_key, "start_elev", "POINT_X", "end_elev", "POINT_X_1"
        ]
        with arcpy.da.SearchCursor(stream, field) as cursor:
            for row in cursor:
                if row[1] > row[3]:
                    continue
                arcpy.FlipLine_edit(stream)  ### TODO: ? all
        self._add_field(stream, "to_node", "DOUBLE", -9999)

        fields = [
            self._primary_key, "POINT_X", "POINT_Y", "POINT_X_1", "POINT_Y_1",
            "to_node"
        ]

        # if stream is saved in gdb, it's id field begins with 1
        # in further computation (stream.py) it would exceed array length
        # MK 4.4.19
        fid_offset_flag = True
        fid_offset = 0
        with arcpy.da.SearchCursor(stream, fields) as cursor_start:
            for row in cursor_start:

                if fid_offset_flag:
                    fid_offset = row[0]
                    fid_offset_flag = False

                a = (row[1], row[2])
                d = row[0] - fid_offset

                with arcpy.da.UpdateCursor(stream, fields) as cursor_end:
                    for row in cursor_end:
                        b = (row[3], row[4])
                        if a == b:
                            row[5] = d
                            cursor_end.updateRow(row)
                        else:
                            row[5] = "-9999"

        self._delete_fields(stream, [
            "SHAPE_LEN", "SHAPE_LE_1", "SHAPE_LE_2", "SHAPE_LE_3",
            "SHAPE_LE_4", "SHAPE_LE_5", "SHAPE_LE_6", "SHAPE_LE_7",
            "SHAPE_LE_8", "SHAPE_LE_9", "SHAPE_L_10", "SHAPE_L_11",
            "SHAPE_L_12", "SHAPE_L_13", "SHAPE_L_14"
        ])

        self._delete_fields(stream, ["ORIG_FID", "ORIG_FID_1", "SHAPE_L_14"])
Ejemplo n.º 10
0
		
# ---------------------------------------------------------------------------

# 12) Select Layer By Attribute, Flip Lines (optional)
flip_ids_str = ''
if flip_routes.lower() == 'yes':
	for i in results['flip']:
		flip_ids_str += (str(i) + ",")
	if len(flip_ids_str) > 0:
		arcpy.SelectLayerByAttribute_management(
			in_layer_or_view = 'road_seg_working', 
			selection_type = "NEW_SELECTION", 
			where_clause = unique_id + " IN (" + flip_ids_str[:-1] + ")"
		)
		arcpy.FlipLine_edit(
			in_features = 'road_seg_working'
		)
		arcpy.AddMessage(str(len(results['flip'])) + " wrongly digitized polyline segments flipped to proper direction.")

# 13) Reclassify Street Operation Attribute Field (optional)
if reclassify.lower() == 'yes':
	twoway_streets_str = ''
	for i in results['twoway']:
		twoway_streets_str += (str(i) + ",")
	arcpy.SelectLayerByAttribute_management(
		in_layer_or_view = 'road_seg_working', 
		selection_type = "NEW_SELECTION", 
		where_clause = unique_id + " IN (" + twoway_streets_str[:-1] + ")"
	)
	arcpy.CalculateField_management("road_seg_working","STREETOPERATION",2,"PYTHON_9.3")
		
Ejemplo n.º 11
0
    rows = arcpy.SearchCursor(NearTableS)
    line = rows.next()
    dS = line.NEAR_DIST

    NearTableE = arcpy.GenerateNearTable_analysis(EPt, OutPt, "NearTable", "",
                                                  "LOCATION", "NO_ANGLE", "")
    rows = arcpy.SearchCursor(NearTableE)
    line = rows.next()
    dE = line.NEAR_DIST
    arcpy.AddMessage(dS)
    arcpy.AddMessage(dE)

    #/orientation of the streamline
    if dS < dE:
        arcpy.AddMessage("   Wrong Direction")
        arcpy.FlipLine_edit(InputFCMTS)
        rows = arcpy.SearchCursor(InputFCMTS)
        line = rows.next()

        ncurrentstep += 1
        arcpy.AddMessage("Extracting the new first point - Step " +
                         str(ncurrentstep) + "/" + str(nstep))
        shapeName = arcpy.Describe(InputFCMTS).shapeFieldName
        SpatialRef = arcpy.Describe(InputFCMTS).spatialReference

        Obj = line.getValue(shapeName)
        first = Obj.firstPoint
        end = Obj.lastPoint
        firstPt = arcpy.PointGeometry(first, SpatialRef)
        endPt = arcpy.PointGeometry(end, SpatialRef)
Ejemplo n.º 12
0
def main():
    #  import required modules and extensions
    import os
    import arcpy
    arcpy.CheckOutExtension('Spatial')

    #  environment settings
    arcpy.env.workspace = 'in_memory' # set workspace to temporary workspace
    arcpy.env.overwriteOutput = True  # set to overwrite output
    sr = arcpy.Describe(nhd_flowline_path).spatialReference

    #  select lines from original nhd that are not coded as pipeline (fcdoe 428**)
    arcpy.MakeFeatureLayer_management(nhd_flowline_path, 'nhd_flowline_lyr')
    quer = """ "FCODE" >=42800 AND "FCODE" <= 42813 """
    arcpy.SelectLayerByAttribute_management('nhd_flowline_lyr', 'NEW_SELECTION', quer)
    arcpy.SelectLayerByAttribute_management('nhd_flowline_lyr', 'SWITCH_SELECTION')
    flowline_network = arcpy.CopyFeatures_management('nhd_flowline_lyr', 'in_memory/flowline_selection')


    #  dissolve flowline network by name
    #flowline_dissolve_name = arcpy.Dissolve_management(flowline_network, 'in_memory/flowline_dissolve', 'GNIS_NAME', '', 'SINGLE_PART', 'UNSPLIT_LINES')
    tmp_flowline_dissolve_name = arcpy.Dissolve_management(flowline_network, 'in_memory/flowline_dissolve_tmp', 'GNIS_NAME', '',
                                                       'SINGLE_PART', 'UNSPLIT_LINES')
    flowline_dissolve_name = arcpy.Sort_management(tmp_flowline_dissolve_name, 'in_memory/flowline_dissolve', [['Shape', 'DESCENDING']], 'PEANO')

    #  create line id field and line length fields
    #  if fields already exist, delete them
    check_fields = ['LineID', 'LineLen', 'SegID', 'SegLen', 'ReachID', 'ReachLen']
    fields = [f.name for f in arcpy.ListFields(flowline_dissolve_name)]
    for field in fields:
        if field in check_fields:
            arcpy.DeleteField_management(flowline_dissolve_name, field)
    arcpy.AddField_management(flowline_dissolve_name, 'StreamName', 'TEXT', 50)
    arcpy.AddField_management(flowline_dissolve_name, 'StreamID', 'LONG')
    arcpy.AddField_management(flowline_dissolve_name, 'StreamLen', 'DOUBLE')
    ct = 1
    with arcpy.da.UpdateCursor(flowline_dissolve_name, ['FID', 'StreamID', 'Shape@Length', 'StreamLen', 'GNIS_NAME', 'StreamName']) as cursor:
        for row in cursor:
            #row[1] = row[0]
            row[1] = ct
            row[3] = row[2]
            row[5] = row[4]
            ct += 1
            cursor.updateRow(row)



    #  dissolve flowline network
    flowline_dissolve_all = arcpy.Dissolve_management(flowline_network, 'in_memory/flowline_dissolve_all', '', '', 'SINGLE_PART', 'UNSPLIT_LINES')
    arcpy.AddField_management(flowline_dissolve_all, 'SegID', 'LONG')
    arcpy.AddField_management(flowline_dissolve_all, 'SegLen', 'DOUBLE')
    with arcpy.da.UpdateCursor(flowline_dissolve_all, ['FID', 'SegID', 'Shape@Length', 'SegLen']) as cursor:
        for row in cursor:
            row[1] = row[0]
            row[3] = row[2]
            cursor.updateRow(row)


    flowline_int = arcpy.Intersect_analysis([flowline_dissolve_name, flowline_dissolve_all], 'in_memory/flowline_int')

    keep = ['FID', 'Shape', 'StreamID', 'StreamLen', 'StreamName', 'SegID', 'SegLen']
    drop = []
    fields = [f.name for f in arcpy.ListFields(flowline_int)]
    for field in fields:
        if field not in keep:
            drop.append(field)
    arcpy.DeleteField_management(flowline_int, drop)

    #  flip lines so segment points are created from end-start of line rather than start-end
    arcpy.FlipLine_edit(flowline_int)

    #  create points at regular interval along each flowline
    seg_pts = arcpy.CreateFeatureclass_management('in_memory', 'seg_pts', 'POINT', '', 'DISABLED', 'DISABLED', sr)
    with arcpy.da.SearchCursor(flowline_int, ['SHAPE@'], spatial_reference = sr) as search:
        with arcpy.da.InsertCursor(seg_pts, ['SHAPE@']) as insert:
            for row in search:
                try:
                    lineGeom = row[0]
                    lineLength = row[0].length
                    lineDist = interval
                    while lineDist + min_segLength <= lineLength:
                        newPoint = lineGeom.positionAlongLine(lineDist)
                        insert.insertRow(newPoint)
                        lineDist += interval
                except Exception as e:
                    arcpy.AddMessage(str(e.message))

    # split flowlines at segment interval points
    flowline_seg = arcpy.SplitLineAtPoint_management(flowline_int, seg_pts, 'in_memory/flowline_seg', 1.0)

    # add and populate reach id and length fields
    arcpy.AddField_management(flowline_seg, 'ReachID', 'SHORT')
    arcpy.AddField_management(flowline_seg, 'ReachLen', 'DOUBLE')
    with arcpy.da.UpdateCursor(flowline_seg, ['FID', 'ReachID', 'Shape@Length', 'ReachLen']) as cursor:
        for row in cursor:
            row[1] = row[0]
            row[3] = row[2]
            cursor.updateRow(row)

    # # get distance along route (LineID) for segment midpoints
    # midpoints =  arcpy.FeatureVerticesToPoints_management(flowline_seg, 'in_memory/midpoints', "MID")
    # arcpy.CopyFeatures_management(midpoints, os.path.join(os.path.dirname(outpath), 'tmp_midpoints.shp'))
    #
    # arcpy.FlipLine_edit(flowline_int)
    # arcpy.AddField_management(flowline_int, 'From_', 'DOUBLE')
    # arcpy.AddField_management(flowline_int, 'To_', 'DOUBLE')
    # with arcpy.da.UpdateCursor(flowline_int, ['SegLen', 'From_', 'To_']) as cursor:
    #     for row in cursor:
    #         row[1] = 0.0
    #         row[2] = row[0]
    #         cursor.updateRow(row)
    #
    #
    # arcpy.CreateRoutes_lr(flowline_int, 'SegID', 'in_memory/flowline_route', 'TWO_FIELDS', 'From_', 'To_')
    # routeTbl = arcpy.LocateFeaturesAlongRoutes_lr(midpoints, 'in_memory/flowline_route', 'SegID',
    #                                                1.0, os.path.join(os.path.dirname(outpath), 'tbl_Routes.dbf'),
    #                                                'RID POINT MEAS')
    #
    # distDict = {}
    # # add reach id distance values to dictionary
    # with arcpy.da.SearchCursor(routeTbl, ['ReachID', 'MEAS']) as cursor:
    #     for row in cursor:
    #         distDict[row[0]] = row[1]
    #
    # # populate dictionary value to output field by ReachID
    # arcpy.AddField_management(flowline_seg, 'ReachDist', 'DOUBLE')
    # with arcpy.da.UpdateCursor(flowline_seg, ['ReachID', 'ReachDist']) as cursor:
    #     for row in cursor:
    #         aKey = row[0]
    #         row[1] = distDict[aKey]
    #         cursor.updateRow(row)
    # #  flip lines back to correct direction
    # arcpy.FlipLine_edit(flowline_seg)

    # save flowline segment output
    arcpy.CopyFeatures_management(flowline_seg, outpath)

    arcpy.Delete_management('in_memory')
Ejemplo n.º 13
0
def main(fcLineNetwork,
         fieldStreamRouteID,
         seed_distance,
         window_sizes,
         stat_fields,
         fcOutputWindows,
         fcOutputSeedPoints,
         tempWorkspace=arcpy.env.scratchWorkspace):
    """Perform a Moving Window Analysis on a Line Network."""

    # Prepare Inputs
    arcpy.AddMessage("Preparing Moving Window Analysis")
    fc_line_dissolve = gis_tools.newGISDataset(tempWorkspace, "GNAT_MWA_LineNetworkDissolved")
    arcpy.Dissolve_management(fcLineNetwork, fc_line_dissolve, fieldStreamRouteID, multi_part=False, unsplit_lines=True)
    arcpy.FlipLine_edit(fc_line_dissolve)

    listSeeds = []
    listgWindows = []
    intSeedID = 0

    # Moving Window Generation
    arcpy.AddMessage("Starting Window Generation")
    iRoutes = int(arcpy.GetCount_management(fc_line_dissolve).getOutput(0))
    arcpy.SetProgressor("step", "Processing Each Route", 0, iRoutes, 1)
    iRoute = 0
    with arcpy.da.SearchCursor(fc_line_dissolve, ["SHAPE@", fieldStreamRouteID, "SHAPE@LENGTH"]) as scLines:
        for fLine in scLines:  # Loop Through Routes
            arcpy.SetProgressorLabel("Route: {} Seed Point: {}".format(iRoute, intSeedID))
            arcpy.SetProgressorPosition(iRoute)
            dblSeedPointPosition = float(max(window_sizes)) / 2  # Start Seeds at position of largest window
            while dblSeedPointPosition + float(max(window_sizes)) / 2 < fLine[2]:
                arcpy.SetProgressorLabel("Route: {} Seed Point: {}".format(iRoute, intSeedID))
                gSeedPointPosition = fLine[0].positionAlongLine(dblSeedPointPosition)
                listSeeds.append([scLines[1], intSeedID, gSeedPointPosition, dblSeedPointPosition])
                for window_size in window_sizes:
                    dblWindowSize = float(window_size)
                    dblLengthStart = dblSeedPointPosition - dblWindowSize / 2
                    dblLengthEnd = dblSeedPointPosition + dblWindowSize / 2
                    listgWindows.append([scLines[1], intSeedID, dblWindowSize, fLine[0].segmentAlongLine(dblLengthStart, dblLengthEnd)])
                dblSeedPointPosition = dblSeedPointPosition + float(seed_distance)
                intSeedID = intSeedID + 1
            iRoute = iRoute + 1

    arcpy.AddMessage("Compiling Moving Windows")
    fcSeedPoints = gis_tools.newGISDataset(tempWorkspace, "GNAT_MWA_SeedPoints")
    fcWindowLines = gis_tools.newGISDataset(tempWorkspace, "GNAT_MWA_WindowLines")
    arcpy.CreateFeatureclass_management(tempWorkspace, "GNAT_MWA_SeedPoints", "POINT", spatial_reference=fcLineNetwork)
    arcpy.CreateFeatureclass_management(tempWorkspace, "GNAT_MWA_WindowLines", "POLYLINE",
                                        spatial_reference=fcLineNetwork)

    gis_tools.resetField(fcSeedPoints, "RouteID", "TEXT")
    gis_tools.resetField(fcSeedPoints, "SeedID", "LONG")
    gis_tools.resetField(fcSeedPoints, "SeedDist", "DOUBLE")

    gis_tools.resetField(fcWindowLines, "RouteID", "TEXT")
    gis_tools.resetField(fcWindowLines, "SeedID", "LONG")
    gis_tools.resetField(fcWindowLines, "Seg", "DOUBLE")

    with arcpy.da.InsertCursor(fcSeedPoints, ["RouteID", "SeedID", "SHAPE@XY", "SeedDist"]) as icSeedPoints:
        for row in listSeeds:
            icSeedPoints.insertRow(row)

    with arcpy.da.InsertCursor(fcWindowLines, ["RouteID", "SeedID", "Seg", "SHAPE@"]) as icWindowLines:
        for row in listgWindows:
            icWindowLines.insertRow(row)

    # Intersecting Network Attributes with Moving Windows
    arcpy.AddMessage("Intersecting Network Attributes with Moving Windows")
    fcIntersected = gis_tools.newGISDataset(tempWorkspace, "GNAT_MWA_IntersectWindowAttributes")
    arcpy.Intersect_analysis([fcWindowLines, fcLineNetwork], fcIntersected, "ALL", output_type="LINE")

    # Use Python Dictionaries for Summary Stats
    # Reference: https://community.esri.com/blogs/richard_fairhurst/2014/11/08/turbo-charging-data-manipulation-with-python-cursors-and-dictionaries
    arcpy.AddMessage("Loading Moving Window Attributes")
    valueDict = {}
    with arcpy.da.SearchCursor(fcIntersected, ["SeedID", "Seg", "SHAPE@LENGTH"] + stat_fields) as searchRows:
        for searchRow in searchRows:
            keyValue = str(searchRow[0])
            segValue = str(searchRow[1])
            if not keyValue in valueDict:
                valueDict[keyValue] = {segValue: [(searchRow[2:])]}
            else:
                if segValue not in valueDict[keyValue]:
                    valueDict[keyValue][segValue] = [(searchRow[2:])]
                else:
                    valueDict[keyValue][segValue].append((searchRow[2:]))

    addfields = ["w{}{}{}".format(str(ws)[:4].rstrip("."), stat, field)[:10] for ws in window_sizes for field in stat_fields for stat in ["N", "Av", "Sm", "Rn", "Mn", "Mx", "Sd", "WA"]]
    for field in addfields:
        gis_tools.resetField(fcSeedPoints, field, "DOUBLE")

    arcpy.AddMessage("Calculating Attribute Statistics")
    with arcpy.da.UpdateCursor(fcSeedPoints, ["SeedID"] + addfields) as ucSeedPoints:
        for row in ucSeedPoints:
            new_row = [row[0]]
            for ws in window_sizes:
                seglen = [segment[0] for segment in valueDict[str(row[0])][str(ws)]]
                for i in range(1, len(stat_fields) + 1):
                    vals = [float(segment[i]) for segment in valueDict[str(row[0])][str(ws)]]
                    count_vals = float(len(vals))
                    sum_vals = sum(vals)
                    ave_vals = sum_vals / float(count_vals)
                    max_vals = max(vals)
                    min_vals = min(vals)
                    range_vals = max_vals - min_vals
                    sd_vals = sqrt(sum([abs(float(x) - float(ave_vals))**2 for x in vals]) / float(count_vals))
                    wave_vals = sum([val / slen for val, slen in zip(vals, seglen)])/ float(count_vals)
                    new_row.extend([count_vals, ave_vals, sum_vals, range_vals, min_vals, max_vals, sd_vals, wave_vals])
            ucSeedPoints.updateRow(new_row)

    # Manage Outputs
    arcpy.AddMessage("Saving Outputs")
    gis_tools.resetData(fcOutputSeedPoints)
    arcpy.CopyFeatures_management(fcSeedPoints, fcOutputSeedPoints)
    gis_tools.resetData(fcOutputWindows)
    arcpy.CopyFeatures_management(fcWindowLines, fcOutputWindows)

    return 0
Ejemplo n.º 14
0
def prepare_streams(dmt, dmt_copy, mat_dmt_fill, null, mat_nan, mat_fd, vpix,
                    spix, rows, cols, ll_corner, NoDataValue, addfield,
                    delfield, output, dmt_clip, intersect, null_shp, gp):

    # creating the geoprocessor object
    gp = arcgisscripting.create()
    # setting the workspace environment
    gp.workspace = gp.GetParameterAsText(
        constants.PARAMETER_PATH_TO_OUTPUT_DIRECTORY)
    # Overwriting output
    arcpy.env.overwriteOutput = 1
    # Check extensions
    arcpy.CheckOutExtension("3D")
    arcpy.CheckOutExtension("Spatial")

    # SET INPUT:
    # Set input
    stream = gp.GetParameterAsText(constants.PARAMETER_STREAM)

    # dmt = data_preparation.dmt
    # dmt_copy = data_preparation.dmt_copy
    # mat_dmt = data_preparation.mat_dmt_fill
    # mat_nan = data_preparation.mat_nan
    # mat_fd = data_preparation.mat_fd
    # vpix = data_preparation.vpix
    # spix = data_preparation.spix
    # rows = data_preparation.rows
    # cols = data_preparation.cols
    # gp = data_preparation.gp
    # ll_corner = data_preparation.ll_corner
    # NoDataValue = data_preparation.NoDataValue
    # addfield = data_preparation.addfield
    # delfield = data_preparation.delfield
    STREAM_RATIO = 1

    # cropped raster info
    dmt_desc = arcpy.Describe(dmt_copy)
    # lower left corner coordinates
    x_coordinate = dmt_desc.extent.XMin
    y_coordinate = dmt_desc.extent.YMin
    arcpy.env.snapRaster = dmt

    # Set output
    # output = data_preparation.output
    temp_dp = output + os.sep + "temp_dp"
    if not os.path.exists(temp_dp):
        os.makedirs(temp_dp)
    tempgdb_dp = arcpy.CreateFileGDB_management(temp_dp, "temp_dp.gdb")

    # WATER FLOWS ACCORDING DMT:
    # dmt_clip = data_preparation.dmt_clip
    dmt_fill, flow_direction, flow_accumulation, slope = arcgis_dmtfce.dmtfce(
        dmt_clip, temp_dp, "TRUE", "TRUE", "NONE")

    # Setnull
    try:
        setnull = arcpy.sa.SetNull(flow_accumulation, 1,
                                   "VALUE < 300")  # hodnota value??
        setnull.save(temp_dp + os.sep + "setnull")
    except:
        prt.message("Unexepted error during setnull calculation:",
                    sys.exc_info()[0])
        raise

    # Stream to feature
    """try:
      toky_dmt = arcpy.sa.StreamToFeature(setnull, flow_direction, temp_dp+os.sep+"toky_dmt", "SIMPLIFY")
  except:
      prt.message("Unexepted error during stream to future calculation:", sys.exc_info()[0])
      raise"""

    # WATER FLOWS ACCORDING DIBAVOD:
    # Clip
    toky = temp_dp + os.sep + "toky.shp"
    tokyLoc = temp_dp + os.sep + "toky.shp"
    # intersect = data_preparation.intersect
    hranice = temp_dp + os.sep + "hranice.shp"
    # null = data_preparation.null_shp
    hranice = arcpy.Clip_analysis(null, intersect, hranice)
    hranice2 = arcpy.Buffer_analysis(hranice,
                                     temp_dp + os.sep + "hranice2.shp",
                                     -spix / 3, "FULL", "ROUND", "NONE")
    # hranice2 = hranice

    toky = arcpy.Clip_analysis(stream, hranice2, toky)

    arcpy.DeleteField_management(toky, [
        "EX_JH", "POZN", "PRPROP_Z", "IDVT", "UTOKJ_ID", "UTOKJN_ID",
        "UTOKJN_F"
    ])

    # Feature vertices to points - START
    prt.message("Feature vertices to points - START...")
    start = arcpy.FeatureVerticesToPoints_management(
        toky, temp_dp + os.sep + "start", "START")
    # Feature vertices to points - END
    prt.message("Feature vertices to points - END...")
    end = arcpy.FeatureVerticesToPoints_management(toky,
                                                   temp_dp + os.sep + "end",
                                                   "END")

    # Extract value to points - END
    prt.message("Extract value to points - END...")
    xxx = temp_dp + os.sep + "end_point"
    end_point = arcpy.sa.ExtractValuesToPoints(end, dmt_clip, xxx, "NONE",
                                               "VALUE_ONLY")
    # Extract value to points - START
    arcpy.AddMessage("Extract value to points - START...")
    xxx = temp_dp + os.sep + "start_point"
    start_point = arcpy.sa.ExtractValuesToPoints(start, dmt_clip, xxx, "NONE",
                                                 "VALUE_ONLY")

    # Join
    arcpy.JoinField_management(toky, "FID", start_point, "ORIG_FID")
    arcpy.JoinField_management(toky, "FID", end_point, "ORIG_FID")
    arcpy.DeleteField_management(toky, [
        "SHAPE_LEN", "SHAPE_LENG", "SHAPE_LE_1", "NAZ_TOK_1", "TOK_ID_1",
        "SHAPE_LE_2", "SHAPE_LE_3", "NAZ_TOK_12", "TOK_ID_12", "SHAPE_LE_4",
        "ORIG_FID_1"
    ])

    # Flip selected lines
    fc = temp_dp + os.sep + "toky.shp"

    field = ["OBJECTID", "RASTERVALU", "RASTERVA_1"]
    prt.message("Flip lines...")  # mat_tok_usek

    # jj tu se zamkne toky a zustane zamcen...
    toky_t = arcpy.MakeFeatureLayer_management(toky,
                                               temp_dp + os.sep + "tok_t.shp")

    arcpy.SelectLayerByAttribute_management(toky_t, "NEW_SELECTION",
                                            "RASTERVALU < RASTERVA_1")
    arcpy.FlipLine_edit(toky_t)
    # arcpy.DeleteField_management(toky_t,
    # ["RASTERVALU","RASTERVA_1","ORIG_FID","ORIG_FID_1"])
    arcpy.DeleteField_management(
        toky, ["RASTERVALU", "RASTERVA_1", "ORIG_FID", "ORIG_FID_1"])

    # Feature vertices to points - START
    prt.message("Feature vertices to points - START...")
    start = arcpy.FeatureVerticesToPoints_management(
        toky, temp_dp + os.sep + "start", "START")
    # Feature vertices to points - END
    prt.message("Feature vertices to points - END...")
    end = arcpy.FeatureVerticesToPoints_management(toky,
                                                   temp_dp + os.sep + "end",
                                                   "END")
    # Extract value to points - START
    prt.message("Extract value to points - START...")
    start_point_check = arcpy.sa.ExtractValuesToPoints(
        start, dmt, temp_dp + os.sep + "start_point_check", "NONE",
        "VALUE_ONLY")
    arcpy.AddXY_management(start_point_check)
    # Extract value to points - END
    prt.message("Extract value to points - END...")
    end_point_check = arcpy.sa.ExtractValuesToPoints(
        end, dmt, temp_dp + os.sep + "end_point_check", "NONE", "VALUE_ONLY")
    arcpy.AddXY_management(end_point_check)

    # Join
    A = arcpy.JoinField_management(toky, "FID", start_point_check, "ORIG_FID")
    B = arcpy.JoinField_management(toky, "FID", end_point_check, "ORIG_FID")
    arcpy.DeleteField_management(
        toky, ["NAZ_TOK_1", "NAZ_TOK_12", "TOK_ID_1", "TOK_ID_12"])

    fc = toky
    field = ["FID", "RASTERVALU", "POINT_X", "RASTERVA_1", "POINT_X_1"]

    with arcpy.da.SearchCursor(fc, field) as cursor:
        for row in cursor:
            if row[1] > row[3]:
                continue
            else:
                prt.message("Flip line")
                arcpy.FlipLine_edit(fc)
    addfield(toky, "to_node", "DOUBLE", -9999)

    fc = toky
    field_end = [
        "FID", "POINT_X", "POINT_Y", "POINT_X_1", "POINT_Y_1", "to_node"
    ]
    field_start = [
        "FID", "POINT_X", "POINT_Y", "POINT_X_1", "POINT_Y_1", "to_node"
    ]
    with arcpy.da.SearchCursor(fc, field_start) as cursor_start:
        for row in cursor_start:
            a = (row[1], row[2])
            d = row[0]
            with arcpy.da.UpdateCursor(fc, field_end) as cursor_end:
                for row in cursor_end:
                    b = (row[3], row[4])
                    if a == b:
                        row[5] = d
                        cursor_end.updateRow(row)
                    else:
                        row[5] = "-9999"

    arcpy.DeleteField_management(toky, [
        "SHAPE_LEN", "SHAPE_LE_1", "SHAPE_LE_2", "SHAPE_LE_3", "SHAPE_LE_4",
        "SHAPE_LE_5", "SHAPE_LE_6", "SHAPE_LE_7", "SHAPE_LE_8", "SHAPE_LE_9",
        "SHAPE_L_10", "SHAPE_L_11", "SHAPE_L_12", "SHAPE_L_13", "SHAPE_L_14"
    ])
    arcpy.DeleteField_management(toky,
                                 ["ORIG_FID", "ORIG_FID_1", "SHAPE_L_14"])

    stream_rst1 = temp_dp + os.sep + "stream_rst"
    stream_rst = arcpy.PolylineToRaster_conversion(toky, "FID", stream_rst1,
                                                   "MAXIMUM_LENGTH", "NONE",
                                                   spix)
    tok_usek = temp_dp + os.sep + "tok_usek"

    arcpy.gp.Reclassify_sa(
        stream_rst, "VALUE", "NoDataValue 1000", tok_usek,
        "DATA")  # jj no data 1000 kdyz in useku bude od 10000
    mat_tok_usek = arcpy.RasterToNumPyArray(temp_dp + os.sep + "tok_usek",
                                            ll_corner, cols, rows)
    mat_tok = arcpy.RasterToNumPyArray(temp_dp + os.sep + "tok_usek",
                                       ll_corner, cols, rows)
    # hit = arcpy.NumPyArrayToRaster(mat_tok_usek,ll_corner,spix)
    # hit.save(temp_dp+"\\hit")
    pocet = len(mat_tok_usek)
    e = range(pocet)  # useky toku + posledni NoData

    cell_stream = []
    # cropped raster info
    reclass_desc = arcpy.Describe(tok_usek)
    ReclNoDataValue = reclass_desc.noDataValue
    mat_tok_usek = mat_tok_usek.astype('int16')

    for i in range(rows):
        for j in range(cols):
            if mat_tok_usek[i][j] < 0:
                mat_tok_usek[i][j] = 0
            else:
                mat_tok_usek[i][j] += 1000
                poz = [mat_tok_usek[i][j], i, j]
                cell_stream.append(poz)

    for i in range(rows):
        for j in range(cols):
            if mat_tok[i][j] != 255:
                mat_tok[i][j] = 3
            else:
                continue

    # hit1 = arcpy.NumPyArrayToRaster(mat_tok,ll_corner,spix)
    # hit1.save(temp_dp+"\\hit1")
    mat_nan = arcpy.NumPyArrayToRaster(mat_nan, ll_corner, spix)
    mat_nan.save(temp_dp + os.sep + "mat_nan")
    # kavka - proc se tu uklada tady

    # HYDRAULIKA TOKU
    addfield(toky, "length", "DOUBLE", 0.0)  # (m)
    # addfield(toky,"vegetace","TEXT", "trava") #tabulka pro drsnosti, vstupem
    # bude tabulka suseky toku - tvar a opevneni(vegetace) ci rovnou drsnost
    # na tvrdo?
    addfield(toky, "sklon", "DOUBLE", 0.0)  # (-)
    # addfield(toky,"drsnost","DOUBLE", 0)
    addfield(toky, "V_infl_ce", "DOUBLE", 0.0)  # (m3)
    addfield(toky, "V_infl_us", "DOUBLE", 0.0)  # (m3)
    addfield(toky, "V_infl", "DOUBLE", 0.0)  # (m3)
    addfield(toky, "Q_outfl", "DOUBLE", 0.0)  # (m3/s)
    addfield(toky, "V_outfl", "DOUBLE", 0.0)  # (m3)
    addfield(toky, "V_outfl_tm", "DOUBLE", 0.0)  # (m3)
    addfield(toky, "V_zbyt", "DOUBLE", 0.0)  # (m3)
    addfield(toky, "V_zbyt_tm", "DOUBLE", 0.0)  # (m3)
    addfield(toky, "V", "DOUBLE", 0.0)  # (m3)
    addfield(toky, "h", "DOUBLE", 0.0)  # (m)
    addfield(toky, "vs", "DOUBLE", 0.0)  # (m/s)
    addfield(toky, "NS", "DOUBLE", 0.0)  # (m)

    addfield(toky, "total_Vic", "DOUBLE", 0.0)  # (m3)
    addfield(toky, "total_Viu", "DOUBLE", 0.0)  # (m3)
    addfield(toky, "max_Q", "DOUBLE", 0.0)  # (m3/s)
    addfield(toky, "max_h", "DOUBLE", 0.0)  # (m)
    addfield(toky, "max_vs", "DOUBLE", 0.0)  # (m/s)
    addfield(toky, "total_Vo", "DOUBLE", 0.0)  # (m3)
    addfield(toky, "total_Vi", "DOUBLE", 0.0)  # (m3)
    addfield(toky, "total_NS", "DOUBLE", 0.0)  # (m3)
    addfield(toky, "total_Vz", "DOUBLE", 0.0)  # (m3)

    # sklon
    fc = toky
    field = [
        "FID", "RASTERVALU", "RASTERVA_1", "sklon", "SHAPE@LENGTH", "length"
    ]
    with arcpy.da.UpdateCursor(fc, field) as cursor:
        for row in cursor:
            sklon_koryta = (row[1] - row[2]) / row[4]
            if sklon_koryta == 0:
                raise ZeroSlopeError(row(0))
            row[3] = sklon_koryta
            cursor.updateRow(row)
            row[5] = row[4]
            cursor.updateRow(row)
    # tvar koryt
    tab_stream_tvar = gp.GetParameterAsText(constants.PARAMETER_STREAMTABLE)
    tab_stream_tvar_code = gp.GetParameterAsText(
        constants.PARAMETER_STREAMTABLE_CODE)

    stream_tvar_dbf = temp_dp + os.sep + "stream_tvar.dbf"
    arcpy.CopyRows_management(tab_stream_tvar, stream_tvar_dbf)
    sfield = ["cislo", "smoderp", "tvar", "b", "m", "drsnost", "Q365"]

    try:
        arcpy.JoinField_management(toky, tab_stream_tvar_code, stream_tvar_dbf,
                                   tab_stream_tvar_code,
                                   "cislo;tvar;b;m;drsnost;Q365")
    except:
        arcpy.AddField_management(toky, "smoderp", "TEXT")
        arcpy.CalculateField_management(toky, "smoderp", "0", "PYTHON")
        arcpy.JoinField_management(toky, tab_stream_tvar_code, stream_tvar_dbf,
                                   tab_stream_tvar_code,
                                   "cislo;tvar;b;m;drsnost;Q365")

    with arcpy.da.SearchCursor(toky, sfield) as cursor:
        for row in cursor:
            for i in range(len(row)):
                if row[i] == " ":
                    prt.message(
                        "Value in tab_stream_tvar are no correct - STOP, check shp file toky in output"
                    )

                    sys.exit()

    fields = arcpy.ListFields(toky)
    # field_names = [field.name for field in fields if field.type !=
    # 'Geometry']
    field_names = [field.name for field in fields]
    toky_tmp = [[] for field in fields]

    for row in arcpy.SearchCursor(toky):
        field_vals = [row.getValue(field) for field in field_names]
        # field_vals
        for i in range(len(field_vals)):
            toky_tmp[i].append(field_vals[i])

    del row

    # all columns names in
    """[u'FID', u'Shape', u'Id', u'Id_1', u'Id_12', u'Id_12_13', u'Id_12_1_14', u'Id_12_1_15', u'RASTERVALU', u'POINT_X', u'POINT_Y', u'Id_12_1_16', u'Id_12_1_17', u'Id_12_1_18', u'RASTERVA_1', u'POINT_X_1', u'POINT_Y_1', u'to_node', u'length', u'sklon', u'V_infl_ce', u'V_infl_us', u'V_infl', u'Q_outfl', u'V_outfl', u'V_outfl_tm', u'V_zbyt', u'V_zbyt_tm', u'V', u'h', u'vs', u'NS', u'total_Vic', u'total_Viu', u'max_Q', u'max_h', u'max_vs', u'total_Vo', u'total_Vi', u'total_NS', u'total_Vz', u'smoderp', u'CISLO', u'TVAR', u'B', u'M', u'DRSNOST', u'Q365']"""

    tokylist = []  # Kubuv vyber
    tokylist.append(toky_tmp[field_names.index('FID')])
    tokylist.append(toky_tmp[field_names.index('POINT_X')])
    tokylist.append(toky_tmp[field_names.index('POINT_Y')])
    tokylist.append(toky_tmp[field_names.index('POINT_X_1')])
    tokylist.append(toky_tmp[field_names.index('POINT_Y_1')])
    tokylist.append(toky_tmp[field_names.index('to_node')])
    tokylist.append(toky_tmp[field_names.index('length')])
    tokylist.append(toky_tmp[field_names.index('sklon')])
    try:
        tokylist.append(toky_tmp[field_names.index('smoderp')])
    except ValueError:
        tokylist.append(toky_tmp[field_names.index('SMODERP')])
    try:
        tokylist.append(toky_tmp[field_names.index('cislo')])
    except ValueError:
        tokylist.append(toky_tmp[field_names.index('CISLO')])
    try:
        tokylist.append(toky_tmp[field_names.index('tvar')])
    except ValueError:
        tokylist.append(toky_tmp[field_names.index('TVAR')])
    try:
        tokylist.append(toky_tmp[field_names.index('b')])
    except ValueError:
        tokylist.append(toky_tmp[field_names.index('B')])
    try:
        tokylist.append(toky_tmp[field_names.index('m')])
    except ValueError:
        tokylist.append(toky_tmp[field_names.index('M')])
    try:
        tokylist.append(toky_tmp[field_names.index('drsnost')])
    except ValueError:
        tokylist.append(toky_tmp[field_names.index('DRSNOST')])
    try:
        tokylist.append(toky_tmp[field_names.index('q365')])
    except ValueError:
        tokylist.append(toky_tmp[field_names.index('Q365')])

    return tokylist, cell_stream, mat_tok_usek, STREAM_RATIO, tokyLoc
Ejemplo n.º 15
0
# -----------------------------------------------------------------------------
#  Copy all input arcs into temp fc for primary direction.
# -----------------------------------------------------------------------------
arc_dir1_lyr = 'arc_dir1_lyr'
arcpy.MakeFeatureLayer_management(in_arc, arc_dir1_lyr)
arcpy.CopyFeatures_management(arc_dir1_lyr, temp_arc_1)
delete_dir2_fields(temp_arc_1)


# -----------------------------------------------------------------------------
#  Process DIRECTIONS = 2 & DIRECTIONS = 3.
# -----------------------------------------------------------------------------
arc_dirs23_lyr = 'arc_dirs23_lyr'
arcpy.MakeFeatureLayer_management(in_arc, arc_dirs23_lyr, """ "DIRECTIONS" IN ('2', '3') """)
arcpy.CopyFeatures_management(arc_dirs23_lyr, temp_arc_2)
arcpy.FlipLine_edit(temp_arc_2)  # Reverse digitized direction
with arcpy.da.UpdateCursor(temp_arc_2, ['ANODE', 'BNODE', 'ABB', 'BEARING']) as cursor:
    for row in cursor:
        anode = row[1]  # Switch ANODE and BNODE
        bnode = row[0]
        baselink = row[2][-1]
        abb = '{0}-{1}-{2}'.format(anode, bnode, baselink)  # Generate new ABB
        bearing = invert_bearing(row[3])
        cursor.updateRow([anode, bnode, abb, bearing])

arc_dir3_lyr = 'arc_dir3_lyr'
arcpy.MakeFeatureLayer_management(temp_arc_2, arc_dir3_lyr, """ "DIRECTIONS" = '3' """)
for field in dir_fields:
    field1 = '{0}1'.format(field)
    field2 = '{0}2'.format(field)
    arcpy.CalculateField_management(arc_dir3_lyr, field1, '!{0}!'.format(field2), 'PYTHON')
Ejemplo n.º 16
0
def FlowPath(in_dem, in_sink, rain_intensity, out_flowpath):
    arcpy.CheckOutExtension("Spatial")
    workspace = os.path.split(out_flowpath)[0]
    arcpy.env.workspace = workspace
    arcpy.env.overwriteOutput = True
    dem = arcpy.Raster(in_dem)
    cell_size = dem.meanCellWidth

    if arcpy.Exists(in_dem) == False:
        arcpy.AddMessage("The input raster does not exist")
        quit()

    if os.path.splitext(out_flowpath)[1].lower() == ".shp":
        FieldOID = "FID"
        FlowDir = os.path.join(workspace, "FlowDir.tif")
        SinkCentroid = os.path.join(workspace, "SinkCentroid.shp")
        CostPath = os.path.join(workspace, "CostPath.tif")
        PathThin = os.path.join(workspace, "PathThin.tif")
        PathLine = os.path.join(workspace, "PathLine.shp")
        PathLineErase = os.path.join(workspace, "PathLineErase.shp")
        Path = os.path.join(workspace, "FlowPath_Raw.shp")
        # Path = out_flowpath
        LineFlip = os.path.join(workspace, "LineFlip.shp")
        LineNoFlip = os.path.join(workspace, "LineNoFlip.shp")
        FlowFrom = os.path.join(workspace, "FlowFrom.shp")
        FlowTo = os.path.join(workspace, "FlowTo.shp")
        PathLineEraseSingle = os.path.join(workspace, "PathLineEraseSingle.shp")
        LineStart = os.path.join(workspace, "LineStart.shp")
        LineEnd = os.path.join(workspace, "LineEnd.shp")
        LineStartElev = os.path.join(workspace, "LineStartElev.shp")
        LineEndElev = os.path.join(workspace, "LineEndElev.shp")
        PathBuffer = os.path.join(workspace, "PathBuffer.shp")
        PathBufferSingle = os.path.join(workspace, "PathBufferSingle.shp")
        FlowFromJoin = os.path.join(workspace, "FlowFromJoin.shp")
        FlowToJoin = os.path.join(workspace, "FlowToJoin.shp")
        FlowFromJoinBuffer = os.path.join(workspace, "FlowFromJoinBuffer.shp")
        FlowToJoinBuffer = os.path.join(workspace, "FlowToJoinBuffer.shp")

    else:
        FieldOID = "OBJECTID"
        FlowDir = os.path.join(workspace, "FlowDir")
        SinkCentroid = os.path.join(workspace, "SinkCentroid")
        CostPath = os.path.join(workspace, "CostPath")
        PathThin = os.path.join(workspace, "PathThin")
        PathLine = os.path.join(workspace, "PathLine")
        PathLineErase = os.path.join(workspace, "PathLineErase")
        Path = os.path.join(workspace, "FlowPath")
        LineFlip = os.path.join(workspace, "LineFlip")
        LineNoFlip = os.path.join(workspace, "LineNoFlip")
        FlowFrom = os.path.join(workspace, "FlowFrom")
        FlowTo = os.path.join(workspace, "FlowTo")
        LineStart = os.path.join(workspace, "LineStart.shp")
        LineEnd = os.path.join(workspace, "LineEnd.shp")
    ### Delineate flow direction
    flow_dir = arcpy.sa.FlowDirection(in_dem)
    flow_dir.save(FlowDir)

    ### Extract the depression polygon centroids
    arcpy.FeatureToPoint_management(in_sink, SinkCentroid, "INSIDE")

    ### Delineate cost path
    cost_path = arcpy.sa.CostPath(SinkCentroid, in_dem, FlowDir, "EACH_CELL", FieldOID)
    cost_path.save(CostPath)

    ### Thin the raster cost path to single-cell width
    path_thin = arcpy.sa.Thin(cost_path, "#", "#", "#", 1)
    path_thin.save(PathThin)

    ### Convert the raster path to vector
    arcpy.RasterToPolyline_conversion(path_thin, PathLine, simplify="NO_SIMPLIFY")

    ### Erase the flow path within depression polygons
    arcpy.Erase_analysis(PathLine, in_sink, PathLineErase)
    arcpy.MultipartToSinglepart_management(PathLineErase, PathLineEraseSingle)
    arcpy.FeatureVerticesToPoints_management(PathLineEraseSingle, LineStart, "START")
    arcpy.FeatureVerticesToPoints_management(PathLineEraseSingle, LineEnd, "END")
    arcpy.sa.ExtractValuesToPoints(LineStart, in_dem, LineStartElev)
    arcpy.sa.ExtractValuesToPoints(LineEnd, in_dem, LineEndElev)
    arcpy.AddField_management(LineStartElev, field_name="FromElev", field_type="FLOAT")
    arcpy.AddField_management(LineEndElev, field_name="ToElev", field_type="FLOAT")
    arcpy.CalculateField_management(
        in_table=LineStartElev,
        field="FromElev",
        expression="!RASTERVALU!",
        expression_type="PYTHON",
        code_block="",
    )
    arcpy.CalculateField_management(
        in_table=LineEndElev,
        field="ToElev",
        expression="!RASTERVALU!",
        expression_type="PYTHON",
        code_block="",
    )
    arcpy.JoinField_management(
        in_data=PathLineEraseSingle,
        in_field="FID",
        join_table=LineStartElev,
        join_field="FID",
        fields="FromElev",
    )
    arcpy.JoinField_management(
        in_data=PathLineEraseSingle,
        in_field="FID",
        join_table=LineEndElev,
        join_field="FID",
        fields="ToElev",
    )
    arcpy.CopyFeatures_management(PathLineEraseSingle, Path)
    # ExtractElevation(PathLineErase, in_dem, Path)

    arcpy.AddField_management(Path, "Flip", "SHORT")

    FromElev = arcpy.AddFieldDelimiters(workspace, "FromElev")
    ToElev = arcpy.AddFieldDelimiters(workspace, "ToElev")
    sql = FromElev + "<" + ToElev
    sql2 = FromElev + ">=" + ToElev

    arcpy.Select_analysis(Path, LineFlip, sql)
    arcpy.CalculateField_management(LineFlip, "Flip", "1", "PYTHON")
    arcpy.FlipLine_edit(LineFlip)
    arcpy.Select_analysis(Path, LineNoFlip, sql2)

    arcpy.Delete_management(Path)
    MergeList = []
    MergeList.append(LineFlip)
    MergeList.append(LineNoFlip)
    arcpy.Merge_management(MergeList, Path)
    arcpy.AddField_management(Path, field_name="StartElev", field_type="FLOAT")
    arcpy.AddField_management(Path, field_name="EndElev", field_type="FLOAT")
    arcpy.AddField_management(Path, field_name="DiffElev", field_type="FLOAT")
    arcpy.AddField_management(Path, field_name="Length", field_type="FLOAT")
    arcpy.CalculateField_management(
        in_table=Path,
        field="StartElev",
        expression="max( !FromElev! , !ToElev! )",
        expression_type="PYTHON",
        code_block="",
    )
    arcpy.CalculateField_management(
        in_table=Path,
        field="EndElev",
        expression="min( !FromElev! , !ToElev! )",
        expression_type="PYTHON",
        code_block="",
    )
    arcpy.CalculateField_management(
        in_table=Path,
        field="DiffElev",
        expression="!StartElev! - !EndElev!",
        expression_type="PYTHON",
        code_block="",
    )
    arcpy.CalculateField_management(
        Path, "Length", "!shape.length@meters!", "PYTHON_9.3", "#"
    )
    arcpy.DeleteField_management(
        in_table=Path,
        drop_field="ARCID;GRID_CODE;FROM_NODE;TO_NODE;ORIG_FID;FromElev;ToElev;Flip",
    )
    sql3 = "Length >" + str(
        2 * cell_size
    )  # if flow path is shorter than 2 pixels, delete
    arcpy.Select_analysis(Path, out_flowpath, sql3)

    arcpy.FeatureVerticesToPoints_management(out_flowpath, FlowFrom, "START")
    arcpy.FeatureVerticesToPoints_management(out_flowpath, FlowTo, "END")
    arcpy.AddField_management(FlowFrom, field_name="FlowFromID", field_type="Long")
    arcpy.AddField_management(FlowTo, field_name="FlowToID", field_type="Long")
    arcpy.CalculateField_management(
        in_table=FlowFrom,
        field="FlowFromID",
        expression="!FID! + 1",
        expression_type="PYTHON",
        code_block="",
    )
    arcpy.CalculateField_management(
        in_table=FlowTo,
        field="FlowToID",
        expression="!FID! + 1",
        expression_type="PYTHON",
        code_block="",
    )
    # derive sink connectivity

    arcpy.Buffer_analysis(
        in_features=Path,
        out_feature_class=PathBuffer,
        buffer_distance_or_field="0.1 Meters",
        line_side="FULL",
        line_end_type="FLAT",
        dissolve_option="ALL",
        dissolve_field="",
        method="PLANAR",
    )
    arcpy.MultipartToSinglepart_management(
        in_features=PathBuffer, out_feature_class=PathBufferSingle
    )
    arcpy.AddField_management(
        PathBufferSingle, field_name="BufferID", field_type="Long"
    )
    arcpy.CalculateField_management(
        in_table=PathBufferSingle,
        field="BufferID",
        expression="!FID! + 1",
        expression_type="PYTHON",
        code_block="",
    )

    search_radius = str(2.1 * cell_size) + " Meters"
    arcpy.SpatialJoin_analysis(
        target_features=FlowFrom,
        join_features=in_sink,
        out_feature_class=FlowFromJoin,
        join_operation="JOIN_ONE_TO_ONE",
        join_type="KEEP_COMMON",
        # field_mapping="""ID "ID" true true false 10 Long 0 10 ,First,#,poly,ID,-1,-1""",
        match_option="INTERSECT",
        search_radius=search_radius,
        distance_field_name="",
    )
    arcpy.SpatialJoin_analysis(
        target_features=FlowTo,
        join_features=in_sink,
        out_feature_class=FlowToJoin,
        join_operation="JOIN_ONE_TO_ONE",
        join_type="KEEP_COMMON",
        # field_mapping="""ID "ID" true true false 10 Long 0 10 ,First,#,poly,ID,-1,-1""",
        match_option="INTERSECT",
        search_radius=search_radius,
        distance_field_name="",
    )
    arcpy.SpatialJoin_analysis(
        target_features=FlowFromJoin,
        join_features=PathBufferSingle,
        out_feature_class=FlowFromJoinBuffer,
        join_operation="JOIN_ONE_TO_ONE",
        join_type="KEEP_COMMON",
        # field_mapping="""ID "ID" true true false 10 Long 0 10 ,First,#,poly,ID,-1,-1""",
        match_option="INTERSECT",
        search_radius=search_radius,
        distance_field_name="",
    )
    arcpy.SpatialJoin_analysis(
        target_features=FlowToJoin,
        join_features=PathBufferSingle,
        out_feature_class=FlowToJoinBuffer,
        join_operation="JOIN_ONE_TO_ONE",
        join_type="KEEP_COMMON",
        # field_mapping="""ID "ID" true true false 10 Long 0 10 ,First,#,poly,ID,-1,-1""",
        match_option="INTERSECT",
        search_radius=search_radius,
        distance_field_name="",
    )
    arcpy.JoinField_management(
        in_data=FlowFromJoinBuffer,
        in_field="BufferID",
        join_table=FlowToJoinBuffer,
        join_field="BufferID",
        fields="ID",
    )
    arcpy.JoinField_management(
        in_data=in_sink,
        in_field="ID",
        join_table=FlowFromJoinBuffer,
        join_field="ID",
        fields="ID_12",
    )
    arcpy.AddField_management(in_sink, field_name="Downstream", field_type="LONG")
    arcpy.CalculateField_management(
        in_table=in_sink,
        field="Downstream",
        expression="!ID_12!",
        expression_type="PYTHON",
        code_block="",
    )
    arcpy.DeleteField_management(in_table=in_sink, drop_field="ID_12")

    arcpy.AddField_management(in_sink, field_name="simu_depth", field_type="FLOAT")
    arcpy.AddField_management(in_sink, field_name="rain_inten", field_type="FLOAT")
    arcpy.AddField_management(in_sink, field_name="time_inund", field_type="FLOAT")
    arcpy.CalculateField_management(
        in_table=in_sink,
        field="simu_depth",
        expression="!volume! / !cat_area!",
        expression_type="PYTHON",
        code_block="",
    )
    arcpy.CalculateField_management(
        in_table=in_sink,
        field="rain_inten",
        expression=rain_intensity,
        expression_type="PYTHON",
        code_block="",
    )
    arcpy.CalculateField_management(
        in_table=in_sink,
        field="time_inund",
        expression="!simu_depth! / !rain_inten!",
        expression_type="PYTHON",
        code_block="",
    )

    arcpy.JoinField_management(
        in_data=out_flowpath,
        in_field="FID",
        join_table=FlowFromJoin,
        join_field="ORIG_FID",
        fields="ID",
    )
    arcpy.AddField_management(
        in_table=out_flowpath, field_name="start_sink", field_type="LONG"
    )
    arcpy.CalculateField_management(
        in_table=out_flowpath,
        field="start_sink",
        expression="!ID!",
        expression_type="PYTHON",
        code_block="",
    )
    arcpy.DeleteField_management(in_table=out_flowpath, drop_field="ID")
    arcpy.JoinField_management(
        in_data=out_flowpath,
        in_field="FID",
        join_table=FlowToJoin,
        join_field="ORIG_FID",
        fields="ID",
    )
    arcpy.AddField_management(
        in_table=out_flowpath, field_name="end_sink", field_type="LONG"
    )
    arcpy.CalculateField_management(
        in_table=out_flowpath,
        field="end_sink",
        expression="!ID!",
        expression_type="PYTHON",
        code_block="",
    )
    arcpy.DeleteField_management(in_table=out_flowpath, drop_field="ID")
    arcpy.JoinField_management(
        in_data=out_flowpath,
        in_field="start_sink",
        join_table=in_sink,
        join_field="ID",
        fields="volume;cat_area;simu_depth;rain_inten;time_inund",
    )

    arcpy.Delete_management(LineFlip)
    arcpy.Delete_management(LineNoFlip)
    arcpy.Delete_management(CostPath)
    arcpy.Delete_management(FlowDir)
    arcpy.Delete_management(PathLineErase)
    arcpy.Delete_management(PathThin)
    arcpy.Delete_management(LineStart)
    arcpy.Delete_management(LineStartElev)
    arcpy.Delete_management(LineEnd)
    arcpy.Delete_management(LineEndElev)
    arcpy.Delete_management(PathLineEraseSingle)
    arcpy.Delete_management(SinkCentroid)
    arcpy.Delete_management(PathLine)
    arcpy.Delete_management(PathBuffer)
    arcpy.Delete_management(PathBufferSingle)
    arcpy.Delete_management(FlowFromJoin)
    arcpy.Delete_management(FlowToJoin)
    arcpy.Delete_management(FlowFromJoinBuffer)
    arcpy.Delete_management(FlowToJoinBuffer)

    arcpy.AddMessage("Flow path delineation done!")
    return out_flowpath