Esempio n. 1
0
def plot_junction_points(line_lyr, network_type):
    """
    Dissolves a network polyline feature class into single part features, intersects the dissolved network
    with itself, and returns a junction point (i.e. tributary confluence) feature class.
    :param fc: network polyline feature class
    :return: point feature class
    """
    line_dslv = "in_memory\\line_dslv"
    gis_tools.newGISDataset("in_memory", line_dslv)
    arcpy.Dissolve_management(line_lyr, line_dslv, "#", "#", "SINGLE_PART")
    pnt_junctions = "in_memory\\{0}_pnt_junctions".format(network_type)
    gis_tools.newGISDataset("in_memory", pnt_junctions)
    arcpy.Intersect_analysis(line_dslv, pnt_junctions, output_type="POINT")
    arcpy.AddXY_management(pnt_junctions)
    return pnt_junctions
Esempio n. 2
0
def getNetworkNodes(inStreamNetwork, scratchWorkspace="in_memory"):
    # Preprocess network
    fcNetworkDissolved = gis_tools.newGISDataset(scratchWorkspace,
                                                 "GNAT_SO_NetworkDissolved")
    arcpy.Dissolve_management(inStreamNetwork,
                              fcNetworkDissolved,
                              multi_part="SINGLE_PART",
                              unsplit_lines="DISSOLVE_LINES")

    fcNetworkIntersectPoints = gis_tools.newGISDataset(
        scratchWorkspace, "GNAT_SO_NetworkIntersectPoints")
    arcpy.Intersect_analysis(fcNetworkDissolved,
                             fcNetworkIntersectPoints,
                             "ALL",
                             output_type="POINT")
    arcpy.AddXY_management(fcNetworkIntersectPoints)
    fcNetworkNodes = gis_tools.newGISDataset(scratchWorkspace,
                                             "GNAT_SO_NetworkNodes")
    arcpy.Dissolve_management(fcNetworkIntersectPoints, fcNetworkNodes,
                              ["POINT_X", "POINT_Y"], "#", "SINGLE_PART")
    del fcNetworkDissolved
    del fcNetworkIntersectPoints
    return fcNetworkNodes
Esempio n. 3
0
def join_node_summary(lyrInputSegments, node_type, lyrNodesToSegments, LineOID, tempWorkspace):
    NODES = "NODES_{0}".format(node_type)
    tblNodeSummary = gis_tools.newGISDataset(tempWorkspace, "tblNode{0}Summary".format(node_type))
    viewNodeSummary = "viewNode{0}Summary".format(node_type)

    arcpy.SelectLayerByAttribute_management(lyrNodesToSegments, "NEW_SELECTION", """"NODE_TYPE" = '{0}'""".format(node_type))
    arcpy.Statistics_analysis(lyrNodesToSegments, tblNodeSummary, [["NODE_TYPE", "COUNT"]], LineOID)
    arcpy.SelectLayerByAttribute_management(lyrNodesToSegments, "CLEAR_SELECTION")

    arcpy.AddField_management(lyrInputSegments, NODES, "TEXT")
    arcpy.MakeTableView_management(tblNodeSummary, viewNodeSummary)
    arcpy.AddJoin_management(lyrInputSegments, LineOID, viewNodeSummary, LineOID, "KEEP_COMMON")
    arcpy.CalculateField_management(lyrInputSegments, NODES, '"!COUNT_NODE_TYPE!"', "PYTHON_9.3")
    arcpy.RemoveJoin_management(lyrInputSegments)
    return
Esempio n. 4
0
def main(inputFCStreamNetwork, inputDistance, strmIndex, segMethod, boolNode,
         boolMerge, outputFCSegments):
    """Segment a stream network into user-defined length intervals."""

    # Get output workspace from output feature class
    out_wspace = os.path.dirname(outputFCSegments)

    # process terminates if input requirements not met
    gis_tools.checkReq(inputFCStreamNetwork)

    lyrStreamNetwork = gis_tools.newGISDataset("LAYER",
                                               "GNAT_SEGMENT_StreamNetwork")
    arcpy.MakeFeatureLayer_management(inputFCStreamNetwork, lyrStreamNetwork)

    strm_nodes = getNetworkNodes(lyrStreamNetwork)
    strm_dslv = r"in_memory\strm_dslv"
    arcpy.Dissolve_management(lyrStreamNetwork, strm_dslv, "BranchID", "",
                              "SINGLE_PART", "DISSOLVE_LINES")

    # Split dissolved network at intersection nodes before segmentation, if option is chosen by user
    if boolNode == "true":
        strm_split_node = r"in_memory\strm_split_node"
        arcpy.SplitLineAtPoint_management(strm_dslv, strm_nodes,
                                          strm_split_node, "0.0001 Meters")
    else:
        strm_split_node = strm_dslv

    # Segment using method with remainder at inflow of each stream reach (i.e. Jesse's method)
    if segMethod == "Remaining segment at inflow (top) of stream branch":
        strm_seg = segOptionA(strm_split_node, inputDistance, out_wspace)
    # Segment using method with remainder at outflow, or divided remainder (i.e. Kelly's method)
    else:
        strm_seg = segOptionBC(strm_split_node, inputDistance, segMethod)

    if boolMerge == 'true':
        arcpy.AddMessage("Merging attributes and geometry from " +
                         inputFCStreamNetwork +
                         " with segmented stream network...")
        arcpy.Intersect_analysis([inputFCStreamNetwork, strm_seg],
                                 outputFCSegments)
    else:
        arcpy.CopyFeatures_management(strm_seg, outputFCSegments)

    # Finalize the process
    ClearInMemory.main()
    arcpy.AddMessage("GNAT: Segmentation process complete!")

    return
Esempio n. 5
0
def snap_junction_points(from_line_lyr, to_line_lyr, search_distance):
    """
    Shifts junction points (i.e. tributary confluences) in the 'From' network to same coordinates
    of junction points in the 'To' network, found within a user-specified search distance.
    :param from_line_lyr: polyline layer representing 'From' stream network
    :param to_line_lyr: polyline layer representing 'To' stream network
    :param search_distance: buffer distance around each 'To' junction point, in meters
    :return: line feature class
    """

    tempWorkspace = "in_memory"

    arcpy.AddMessage("GNAT TLA: snapping junction points in 'From' network to 'To' network")

    snapped_from_line = gis_tools.newGISDataset(tempWorkspace, "snapped_from_line")
    arcpy.CopyFeatures_management(from_line_lyr, snapped_from_line)
    snap_line_lyr  = gis_tools.newGISDataset("Layer", "snap_line_lyr")
    arcpy.MakeFeatureLayer_management(snapped_from_line, snap_line_lyr)

    list_field_objects = arcpy.ListFields(snap_line_lyr)
    list_from_fields = [f.name for f in list_field_objects if f.type != "OID" and f.type != "Geometry"]

    # Plot junction points for 'From' and 'To' stream networks
    from_junction_pnts = plot_junction_points(snap_line_lyr, "from")
    to_junction_pnts = plot_junction_points(to_line_lyr, "to")
    lyr_from_junc_pnts = gis_tools.newGISDataset("Layer", "lyr_from_junc_pnts")
    arcpy.MakeFeatureLayer_management(from_junction_pnts, lyr_from_junc_pnts)

    from_line_oidfield = arcpy.Describe(snap_line_lyr).OIDFieldName

    from_vrtx = gis_tools.newGISDataset(tempWorkspace, "from_vrtx")
    arcpy.FeatureVerticesToPoints_management(snap_line_lyr, from_vrtx, point_location="ALL")
    arcpy.AddXY_management(from_vrtx)
    from_vrtx_lyr = gis_tools.newGISDataset("Layer", "from_vrtx_lyr")
    arcpy.MakeFeatureLayer_management(from_vrtx, from_vrtx_lyr)
    arcpy.Near_analysis(from_vrtx_lyr, to_junction_pnts, search_distance, "LOCATION")
    arcpy.SelectLayerByLocation_management(from_vrtx_lyr, "INTERSECT", lyr_from_junc_pnts, "#", "NEW_SELECTION")
    update_xy_coord(from_vrtx_lyr)
    arcpy.MakeXYEventLayer_management(from_vrtx_lyr, "POINT_X", "POINT_Y", "xy_events", from_vrtx_lyr)
    xy_events_pnt = gis_tools.newGISDataset(tempWorkspace, "xy_events_pnt")
    arcpy.CopyFeatures_management("xy_events", xy_events_pnt)
    arcpy.MakeFeatureLayer_management(xy_events_pnt, "xy_events_lyr")
    xy_line = gis_tools.newGISDataset(tempWorkspace, "xy_line")
    arcpy.PointsToLine_management("xy_events_lyr", xy_line, "ORIG_FID")
    arcpy.JoinField_management(xy_line, "ORIG_FID", snap_line_lyr, from_line_oidfield, list_from_fields)
    arcpy.DeleteFeatures_management(snap_line_lyr)
    arcpy.Append_management(xy_line, snap_line_lyr, "NO_TEST")
    return snap_line_lyr
Esempio n. 6
0
def segOptionBC(fcDissolvedStreamBranch,
                inputDistance,
                segMethod,
                fcTempStreamNetwork=r"in_memory\temp_network",
                outSegmentIDField="SegmentID",
                scratchWorkspace=r"in_memory"):
    """Segment the input stream network feature class using one of two methods:

    1. Remainder at the outflow of each stream reach
    2. Remainder is divided amongst each stream segment
    """

    gis_tools.resetData(fcTempStreamNetwork)
    listPoints = []

    if segMethod == "Remaining segment at outflow (bottom) of stream branch":
        arcpy.AddMessage(
            "Segmenting using the remainder at stream branch outflow method..."
        )
    else:
        arcpy.AddMessage(
            "Segmenting using the segment remainder division method...")

    with arcpy.da.SearchCursor(fcDissolvedStreamBranch,
                               ["SHAPE@", "SHAPE@LENGTH"]) as scBranches:
        for row in scBranches:
            gLine = row[0]
            dblPointPosition = 0
            if segMethod == "Remaining segment at outflow (bottom) of stream branch":
                while dblPointPosition < row[1]:
                    listPoints.append(
                        gLine.positionAlongLine(dblPointPosition))
                    dblPointPosition += Decimal(inputDistance)
            else:
                intNumberOfPositions = int(
                    Decimal(row[1]) / Decimal(inputDistance))
                for intPosition in range(intNumberOfPositions):

                    dblProportionalPosition = float(
                        intPosition) / intNumberOfPositions
                    listPoints.append(
                        gLine.positionAlongLine(dblProportionalPosition, True))

    fcSplitPoints = gis_tools.newGISDataset(scratchWorkspace,
                                            "GNAT_SEG_SplitPoints")
    arcpy.CreateFeatureclass_management(
        scratchWorkspace,
        "GNAT_SEG_SplitPoints",
        "POINT",
        spatial_reference=fcDissolvedStreamBranch)

    with arcpy.da.InsertCursor(fcSplitPoints, ["SHAPE@"]) as icSplitPoints:
        for point in listPoints:
            icSplitPoints.insertRow([point])
    arcpy.SplitLineAtPoint_management(fcDissolvedStreamBranch, fcSplitPoints,
                                      fcTempStreamNetwork, "1 Meters")
    gis_tools.addUniqueIDField(fcTempStreamNetwork, outSegmentIDField)

    # Remove unnecessary fields
    fieldObjects = arcpy.ListFields(fcTempStreamNetwork)
    oidField = arcpy.Describe(fcTempStreamNetwork).OIDFieldName
    shapeField = arcpy.Describe(fcTempStreamNetwork).shapeFieldName
    lengthField = arcpy.Describe(fcTempStreamNetwork).lengthFieldName
    keepFields = [oidField, shapeField, lengthField, outSegmentIDField]
    for field in fieldObjects:
        if field.name not in keepFields:
            arcpy.DeleteField_management(fcTempStreamNetwork, [field.name])

    # Clean up
    del fcSplitPoints

    return fcTempStreamNetwork
Esempio n. 7
0
def main(fcFromLine,
         fcToLine,
         fcOutputLineNetwork,
         searchDistance,
         tempWorkspace):

    reload(DividePolygonBySegment)

    # Environment settings
    arcpy.env.overwriteOutput = True
    arcpy.env.outputMFlag = "Disabled"
    arcpy.env.outputZFlag = "Disabled"
    arcpy.env.scratchWorkspace = tempWorkspace

    arcpy.AddMessage("GNAT TLA: starting transfer process...")

    gis_tools.resetData(fcOutputLineNetwork)
    fcFromLineTemp = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_FromLineTemp")
    fcToLineTemp = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_ToLineTemp")
    arcpy.MakeFeatureLayer_management(fcFromLine, "lyrFromLine")
    arcpy.MakeFeatureLayer_management(fcToLine, "lyrToLine")
    arcpy.CopyFeatures_management("lyrFromLine", fcFromLineTemp)
    arcpy.CopyFeatures_management("lyrToLine", fcToLineTemp)

    # Add a unique ID for the "From" line feature class
    from_oid = arcpy.Describe(fcFromLineTemp).OIDFieldName
    arcpy.AddField_management(fcFromLineTemp, "FromID", "LONG")
    arcpy.CalculateField_management(fcFromLineTemp, "FromID", "!{0}!".format(from_oid), "PYTHON_9.3")

    # Snap "From" line network to "To" line network
    lyrFromLineTemp = gis_tools.newGISDataset("Layer", "lyrFromLineTemp")
    lyrToLineTemp = gis_tools.newGISDataset("Layer", "lyrToLineTemp")
    arcpy.MakeFeatureLayer_management(fcFromLineTemp, lyrFromLineTemp)
    arcpy.MakeFeatureLayer_management(fcToLineTemp, lyrToLineTemp)
    lyrSnapFromLine = snap_junction_points(lyrFromLineTemp, lyrToLineTemp, searchDistance)

    # Make bounding polygon for "From" line feature class
    # arcpy.AddMessage("GNAT TLA: Create buffer polygon around 'From' network")
    # fcFromLineBuffer = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_FromLineBuffer")
    # arcpy.Buffer_analysis(lyrSnapFromLine, fcFromLineBuffer, "{0} Meters".format(searchDistance * 3), "FULL", "ROUND", "ALL")
    # fcFromLineBufDslv = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_FromLineBUfDslv")
    # arcpy.AddMessage("GNAT TLA: Dissolve buffer")
    # arcpy.Dissolve_management(fcFromLineBuffer, fcFromLineBufDslv)

    merge_lines = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_merged_lines")
    arcpy.Merge_management([lyrSnapFromLine, lyrToLineTemp], merge_lines)
    fcFromLineBuffer = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_FromLineBUfDslv")
    external_edge_buffer(merge_lines, 10, fcFromLineBuffer)

    # Select features from "To" line feature class that are inside "From" line buffer
    arcpy.AddMessage("GNAT TLA: Select 'To' line features inside 'From' buffer")
    lyrFromLineBuffer = gis_tools.newGISDataset("Layer", "lyrFromLineBuffer")
    arcpy.MakeFeatureLayer_management(fcFromLineBuffer, lyrFromLineBuffer)
    lyrToLine = gis_tools.newGISDataset("Layer", "lyrToLine")
    arcpy.MakeFeatureLayer_management(fcToLine, lyrToLine)
    arcpy.SelectLayerByLocation_management(lyrToLine, "WITHIN", lyrFromLineBuffer, "#", "NEW_SELECTION")
    fcToLineWithinFromBuffer = arcpy.FeatureClassToFeatureClass_conversion(lyrToLine, tempWorkspace, "GNAT_TLA_ToLineWithinFromBuffer")

    # Select features from "To" line feature class that are outside "From" line buffer
    arcpy.SelectLayerByAttribute_management(lyrToLine, "SWITCH_SELECTION")
    fcToLineOutsideFromBuffer = arcpy.FeatureClassToFeatureClass_conversion(lyrToLine, tempWorkspace, "GNAT_TLA_ToLineOutsideFromBuffer")

    # Segment "From" line buffer polygon
    arcpy.AddMessage("GNAT TLA: Segmenting 'From' line buffer polygon")
    fcSegmentedBoundingPolygons = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_SegmentedBoundingPolygons")

    DividePolygonBySegment.main(lyrSnapFromLine, fcFromLineBuffer, fcSegmentedBoundingPolygons, 10.0, 150.0, tempWorkspace)

    # Split points of "To" line at intersection of polygon segments
    arcpy.AddMessage("GNAT TLA: Split 'To' line features")
    fcIntersectSplitPoints = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_IntersectSplitPoints")
    arcpy.Intersect_analysis([fcToLineWithinFromBuffer, fcSegmentedBoundingPolygons], fcIntersectSplitPoints, output_type="POINT")
    fcSplitLines = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_SplitLines")
    arcpy.SplitLineAtPoint_management(fcToLineWithinFromBuffer, fcIntersectSplitPoints, fcSplitLines, "0.1 METERS")

    # Spatial join lines based on a common field, as transferred by segmented polygon
    arcpy.AddMessage("GNAT TLA: Joining polygon segments")
    arcpy.SpatialJoin_analysis(fcSplitLines,
                               fcSegmentedBoundingPolygons,
                               fcOutputLineNetwork,
                               "JOIN_ONE_TO_ONE",
                               "KEEP_ALL",
                               match_option="WITHIN")
    arcpy.JoinField_management(fcOutputLineNetwork, "FromID", fcFromLineTemp, "FromID")

    # Append the "To" lines that were outside of the "From" line buffer, which will have NULL or zero values
    arcpy.env.extent = fcToLine # changed earlier in the workflow in DividePolygonBySegment module
    arcpy.Append_management([fcToLineOutsideFromBuffer], fcOutputLineNetwork, "NO_TEST")

    # Change values of "From" features to -99999 if no "To" features to transfer to.
    arcpy.MakeFeatureLayer_management(fcOutputLineNetwork, "lyrOutputLineNetwork")
    arcpy.SelectLayerByLocation_management("lyrOutputLineNetwork", "ARE_IDENTICAL_TO", fcToLineOutsideFromBuffer, "#", "NEW_SELECTION")
    to_fields = [f.name for f in arcpy.ListFields(fcToLine)]
    empty_attributes("lyrOutputLineNetwork", to_fields)
    arcpy.SelectLayerByAttribute_management("lyrOutputLineNetwork", "CLEAR_SELECTION")

    arcpy.AddMessage("GNAT TLA: Tool complete")

    return
Esempio n. 8
0
def main(fcInputCenterline,
         fcInputPolygon,
         fcSegmentedPolygons,
         dblPointDensity=10.0,
         dblJunctionBuffer=100.00,
         workspaceTemp="in_memory"):

    # Manage Environments
    env_extent = arcpy.env.extent
    env_outputmflag = arcpy.env.outputMFlag
    env_outputzflag = arcpy.env.outputZFlag
    arcpy.env.outputMFlag = "Disabled"
    arcpy.env.outputZFlag = "Disabled"
    arcpy.env.extent = fcInputPolygon  ## Set full extent to build Thiessan polygons over entire line network.

    # Copy centerline to temporary workspace
    fcCenterline = gis_tools.newGISDataset(workspaceTemp,
                                           "GNAT_DPS_Centerline")
    arcpy.CopyFeatures_management(fcInputCenterline, fcCenterline)

    if "FromID" not in [
            field.name for field in arcpy.ListFields(fcCenterline)
    ]:
        arcpy.AddField_management(fcCenterline, "FromID", "LONG")
        arcpy.CalculateField_management(
            fcCenterline, "FromID",
            "!{}!".format(arcpy.Describe(fcCenterline).OIDFieldName),
            "PYTHON_9.3")

    # Build Thiessan polygons
    arcpy.AddMessage("GNAT DPS: Building Thiessan polygons")

    arcpy.Densify_edit(fcCenterline, "DISTANCE",
                       "{} METERS".format(dblPointDensity))

    fcTribJunctionPoints = gis_tools.newGISDataset(
        workspaceTemp, "GNAT_DPS_TribJunctionPoints")
    arcpy.Intersect_analysis([fcCenterline],
                             fcTribJunctionPoints,
                             output_type="POINT")

    fcThiessanPoints = gis_tools.newGISDataset(workspaceTemp,
                                               "GNAT_DPS_ThiessanPoints")
    arcpy.FeatureVerticesToPoints_management(fcCenterline, fcThiessanPoints,
                                             "ALL")

    lyrThiessanPoints = gis_tools.newGISDataset("Layer", "lyrThiessanPoints")
    arcpy.MakeFeatureLayer_management(fcThiessanPoints, lyrThiessanPoints)
    arcpy.SelectLayerByLocation_management(
        lyrThiessanPoints, "INTERSECT", fcTribJunctionPoints,
        "{} METERS".format(dblJunctionBuffer))

    fcThiessanPoly = gis_tools.newGISDataset(workspaceTemp,
                                             "GNAT_DPS_ThiessanPoly")
    # arcpy.CreateThiessenPolygons_analysis(lyrThiessanPoints,fcThiessanPoly,"ONLY_FID")
    arcpy.CreateThiessenPolygons_analysis(lyrThiessanPoints, fcThiessanPoly,
                                          "ALL")

    # Clean polygons
    # lyrInputPolygon = gis_tools.newGISDataset("Layer", "lyrInputPolygon")
    # arcpy.MakeFeatureLayer_management(fcInputPolygon, lyrInputPolygon)
    arcpy.RepairGeometry_management(fcInputPolygon, "KEEP_NULL")

    fcThiessanPolyClip = gis_tools.newGISDataset(workspaceTemp,
                                                 "GNAT_DPS_TheissanPolyClip")
    arcpy.Clip_analysis(fcThiessanPoly, fcInputPolygon, fcThiessanPolyClip)

    # Split the junction Thiessan polygons
    arcpy.AddMessage("GNAT DPS: Split junction Thiessan polygons")
    lyrTribThiessanPolys = gis_tools.newGISDataset("Layer",
                                                   "lyrTribThiessanPolys")
    arcpy.MakeFeatureLayer_management(fcThiessanPolyClip, lyrTribThiessanPolys)
    arcpy.SelectLayerByLocation_management(lyrTribThiessanPolys, "INTERSECT",
                                           fcTribJunctionPoints)

    fcSplitPoints = gis_tools.newGISDataset(workspaceTemp,
                                            "GNAT_DPS_SplitPoints")
    arcpy.Intersect_analysis([lyrTribThiessanPolys, fcCenterline],
                             fcSplitPoints,
                             output_type="POINT")

    arcpy.AddMessage("GNAT DPS: Moving starting vertices of junction polygons")
    geometry_functions.changeStartingVertex(fcTribJunctionPoints,
                                            lyrTribThiessanPolys)

    arcpy.AddMessage("GNAT DPS: Vertices moved")
    fcThiessanTribPolyEdges = gis_tools.newGISDataset(
        workspaceTemp, "GNAT_DPS_ThiessanTribPolyEdges")
    arcpy.FeatureToLine_management(lyrTribThiessanPolys,
                                   fcThiessanTribPolyEdges)

    fcSplitLines = gis_tools.newGISDataset(workspaceTemp,
                                           "GNAT_DPS_SplitLines")
    arcpy.SplitLineAtPoint_management(fcThiessanTribPolyEdges, fcSplitPoints,
                                      fcSplitLines, "0.1 METERS")

    fcMidPoints = gis_tools.newGISDataset(workspaceTemp, "GNAT_DPS_MidPoints")
    arcpy.FeatureVerticesToPoints_management(fcSplitLines, fcMidPoints, "MID")
    arcpy.Near_analysis(fcMidPoints, fcTribJunctionPoints, location="LOCATION")
    arcpy.AddXY_management(fcMidPoints)

    fcTribToMidLines = gis_tools.newGISDataset(workspaceTemp,
                                               "GNAT_DPS_TribToMidLines")
    arcpy.XYToLine_management(fcMidPoints, fcTribToMidLines, "POINT_X",
                              "POINT_Y", "NEAR_X", "NEAR_Y")

    ### Select polygons by centerline ###
    arcpy.AddMessage("GNAT DPS: Select polygons by centerline")
    fcThiessanEdges = gis_tools.newGISDataset(workspaceTemp,
                                              "GNAT_DPS_ThiessanEdges")
    arcpy.FeatureToLine_management(fcThiessanPolyClip, fcThiessanEdges)

    fcAllEdges = gis_tools.newGISDataset(workspaceTemp, "GNAT_DPS_AllEdges")
    arcpy.Merge_management([fcTribToMidLines, fcThiessanEdges, fcCenterline],
                           fcAllEdges)  # include fcCenterline if needed

    fcAllEdgesPolygons = gis_tools.newGISDataset(workspaceTemp,
                                                 "GNAT_DPS_AllEdgesPolygons")
    arcpy.FeatureToPolygon_management(fcAllEdges, fcAllEdgesPolygons)

    fcAllEdgesPolygonsClip = gis_tools.newGISDataset(
        workspaceTemp, "GNAT_DPS_AllEdgesPolygonsClip")
    arcpy.Clip_analysis(fcAllEdgesPolygons, fcInputPolygon,
                        fcAllEdgesPolygonsClip)

    fcPolygonsJoinCenterline = gis_tools.newGISDataset(
        workspaceTemp, "GNAT_DPS_PolygonsJoinCenterline")
    arcpy.SpatialJoin_analysis(fcAllEdgesPolygonsClip,
                               fcCenterline,
                               fcPolygonsJoinCenterline,
                               "JOIN_ONE_TO_MANY",
                               "KEEP_ALL",
                               match_option="SHARE_A_LINE_SEGMENT_WITH")

    fcPolygonsDissolved = gis_tools.newGISDataset(
        workspaceTemp, "GNAT_DPS_PolygonsDissolved")
    arcpy.Dissolve_management(fcPolygonsJoinCenterline,
                              fcPolygonsDissolved,
                              "FromID",
                              multi_part="SINGLE_PART")

    lyrPolygonsDissolved = gis_tools.newGISDataset("Layer",
                                                   "lyrPolygonsDissolved")
    arcpy.MakeFeatureLayer_management(fcPolygonsDissolved,
                                      lyrPolygonsDissolved)
    arcpy.SelectLayerByAttribute_management(lyrPolygonsDissolved,
                                            "NEW_SELECTION",
                                            """ "FromID" IS NULL """)

    arcpy.Eliminate_management(lyrPolygonsDissolved, fcSegmentedPolygons,
                               "LENGTH")

    arcpy.AddMessage("GNAT DPS: Tool complete")

    # Reset env
    arcpy.env.extent = env_extent
    arcpy.env.outputMFlag = env_outputmflag
    arcpy.env.outputZFlag = env_outputzflag

    return
Esempio n. 9
0
def main(inputFCPolylineNetwork,
         inputDownstreamID,
         outputFCPolylineStreamOrder,
         outputFCIntersectPoints,
         scratchWorkspace= "in_memory"):

    # Set processing environments
    arcpy.env.outputMflag = "Disabled"
    arcpy.env.outputZflag = "Disabled"

    # Initialize stream order
    intCurrentOrder = 1

    if arcpy.Exists(outputFCPolylineStreamOrder):
       arcpy.Delete_management(outputFCPolylineStreamOrder)
    if arcpy.Exists(outputFCIntersectPoints):
        arcpy.Delete_management(outputFCIntersectPoints)

    # Preprocess network
    fcNetworkDissolved = gis_tools.newGISDataset(scratchWorkspace, "GNAT_SO_NetworkDissolved")
    arcpy.Dissolve_management(inputFCPolylineNetwork, fcNetworkDissolved, multi_part="SINGLE_PART",
                             unsplit_lines="DISSOLVE_LINES")
    
    fcNetworkIntersectPoints = gis_tools.newGISDataset(scratchWorkspace, "GNAT_SO_NetworkIntersectPoints")
    arcpy.Intersect_analysis(fcNetworkDissolved, fcNetworkIntersectPoints, "ALL", output_type="POINT")
    arcpy.AddXY_management(fcNetworkIntersectPoints)
    fcNetworkNodes = gis_tools.newGISDataset(scratchWorkspace, "GNAT_SO_NetworkNodes")
    arcpy.Dissolve_management(fcNetworkIntersectPoints,fcNetworkNodes, ["POINT_X", "POINT_Y"], "#", "SINGLE_PART")

    listFields = arcpy.ListFields(fcNetworkDissolved,"strm_order")
    if len(listFields) == 0:
        arcpy.AddField_management(fcNetworkDissolved,"strm_order","LONG")
    arcpy.CalculateField_management(fcNetworkDissolved,"strm_order",0,"PYTHON")

    lyrA = gis_tools.newGISDataset("LAYER", "lyrA")
    lyrB = gis_tools.newGISDataset("LAYER", "lyrB")
    lyrCalculate = gis_tools.newGISDataset("LAYER", "lyrCalculate")
    
    arcpy.MakeFeatureLayer_management(fcNetworkDissolved,lyrA)
    arcpy.MakeFeatureLayer_management(fcNetworkDissolved,lyrB)
    arcpy.MakeFeatureLayer_management(fcNetworkDissolved,lyrCalculate)

    # Determine order 1 streams as initial condition
    fcDangles = gis_tools.newGISDataset(scratchWorkspace, "GNAT_SO_Dangles")
    arcpy.FeatureVerticesToPoints_management(inputFCPolylineNetwork,fcDangles,"DANGLE")
    lyrDangles = gis_tools.newGISDataset("LAYER", "lyrDangles")
    where = '"ORIG_FID" <> ' + str(inputDownstreamID)
    arcpy.MakeFeatureLayer_management(fcDangles,lyrDangles,where)

    arcpy.SelectLayerByLocation_management(lyrA,"INTERSECT",lyrDangles,selection_type="NEW_SELECTION")
    arcpy.CalculateField_management(lyrA,"strm_order",intCurrentOrder,"PYTHON")
    
    fcStreamOrderTransistionPoints = gis_tools.newGISDataset(scratchWorkspace, "GNAT_SO_StreamOrderTransistionPoints")

    # Iterate through stream orders
    arcpy.AddMessage("Evaluating Stream Order: " + str(intCurrentOrder))
    arcpy.SelectLayerByAttribute_management(lyrCalculate,"NEW_SELECTION",'"strm_order" = 0')
    intFeaturesRemaining = int(arcpy.GetCount_management(lyrCalculate).getOutput(0))
    intIteration = 1
    listPairsRetired = []
    while intFeaturesRemaining <> 0:
        arcpy.AddMessage("    Iteration: " + str(intIteration) + " |Features Remaining: " + str(intFeaturesRemaining))

        listPairs = newListPairs(intCurrentOrder)
        for pair in listPairs:
            if pair not in listPairsRetired:
                fcIntersectPoints = gis_tools.newGISDataset(scratchWorkspace, "GNAT_SO_IntersectPoints_" + str(intIteration) + "_Pair_" + str(pair[0]) + "_" + str(pair[1]) + "_Order_" + str(intCurrentOrder))
                lyrIntersectPoints = gis_tools.newGISDataset("LAYER", "lyrIntersectPoints" + str(intIteration) + str(pair[0]) + str(pair[1]))
                if pair[0] == pair[1]:
                    arcpy.SelectLayerByAttribute_management(lyrA,"NEW_SELECTION",'"strm_order" = ' + str(pair[0]))
                    arcpy.Intersect_analysis(lyrA,fcIntersectPoints,output_type="POINT")
                    arcpy.MakeFeatureLayer_management(fcIntersectPoints,lyrIntersectPoints)
                    arcpy.SelectLayerByAttribute_management(lyrCalculate,"NEW_SELECTION",'"strm_order" = 0')
                    arcpy.SelectLayerByLocation_management(lyrIntersectPoints,"INTERSECT",lyrCalculate,selection_type="NEW_SELECTION")
                    if arcpy.Exists(fcStreamOrderTransistionPoints):
                        arcpy.Append_management(lyrIntersectPoints,fcStreamOrderTransistionPoints)
                    else:
                        arcpy.CopyFeatures_management(lyrIntersectPoints,fcStreamOrderTransistionPoints)
                    arcpy.SelectLayerByLocation_management(lyrCalculate,"INTERSECT",fcIntersectPoints,selection_type="SUBSET_SELECTION")
                    if int(arcpy.GetCount_management(lyrCalculate).getOutput(0)) > 0 and pair[0] == intCurrentOrder:
                        intCurrentOrder = intCurrentOrder + 1
                        arcpy.AddMessage("New Stream Order: " + str(intCurrentOrder))
                    arcpy.CalculateField_management(lyrCalculate,"strm_order",int(intCurrentOrder),"PYTHON")

                else:
                    arcpy.SelectLayerByAttribute_management(lyrA,"NEW_SELECTION",'"strm_order" = ' + str(pair[0]))
                    arcpy.SelectLayerByAttribute_management(lyrB,"NEW_SELECTION",'"strm_order" = ' + str(pair[1]))
                    arcpy.Intersect_analysis([lyrA,lyrB],fcIntersectPoints,output_type="POINT")
                    arcpy.SelectLayerByAttribute_management(lyrCalculate,"NEW_SELECTION",'"strm_order" = 0')
                    arcpy.SelectLayerByLocation_management(lyrCalculate,"INTERSECT",fcIntersectPoints,selection_type="SUBSET_SELECTION")
                    arcpy.CalculateField_management(lyrCalculate,"strm_order",int(max(pair)),"PYTHON")

        # Set up next round
        arcpy.SelectLayerByAttribute_management(lyrCalculate,"NEW_SELECTION",'"strm_order" = 0')
        intFeaturesCurrent = int(arcpy.GetCount_management(lyrCalculate).getOutput(0))
        if intFeaturesRemaining == intFeaturesCurrent:
            arcpy.AddError("The number of features remaining (" + str(intFeaturesCurrent) + " is the same as the last iteration.")
            break
        else:
            intFeaturesRemaining = intFeaturesCurrent
        intIteration = intIteration + 1

    # Outputs
    arcpy.Intersect_analysis([fcNetworkDissolved,inputFCPolylineNetwork],outputFCPolylineStreamOrder)
        
    arcpy.DeleteIdentical_management(fcStreamOrderTransistionPoints, "Shape")
    arcpy.CopyFeatures_management(fcNetworkNodes, outputFCIntersectPoints)
    # arcpy.CopyFeatures_management(fcNetworkIntersectPoints, outputFCIntersectPoints)

    ClearInMemory.main()

    return outputFCPolylineStreamOrder, outputFCIntersectPoints
Esempio n. 10
0
def main(fcInput, fieldName="Sin", workspaceTmp="in_memory"):

    # Get list of fields from input feature class
    keepFields = [keepField.name for keepField in arcpy.ListFields(fcInput)]
    keepFields.append(fieldName)
    keepFields.append("InputID")

    # Prepare inputs
    fieldInputID = gis_tools.resetField(fcInput, "InputID", "DOUBLE")
    arcpy.CalculateField_management(
        fcInput, fieldInputID,
        "!" + arcpy.Describe(fcInput).OIDFieldName + "!", "PYTHON_9.3")
    fcInputTmp = gis_tools.newGISDataset(workspaceTmp, "fcIn")
    arcpy.CopyFeatures_management(fcInput, fcInputTmp)
    fieldSinuosity = gis_tools.resetField(fcInputTmp, fieldName, "DOUBLE")
    fieldSegmentLength = gis_tools.resetField(fcInputTmp, "SgLen", "DOUBLE")

    # Find length of segment
    arcpy.CalculateField_management(fcInputTmp, fieldSegmentLength,
                                    "!shape.length!", "PYTHON_9.3")

    # Find straight line distance
    fcSegmentEnds = gis_tools.newGISDataset(workspaceTmp, "SgEnd")
    arcpy.FeatureVerticesToPoints_management(fcInputTmp, fcSegmentEnds,
                                             "BOTH_ENDS")

    fcSegmentDistances = gis_tools.newGISDataset(workspaceTmp, "SgDst")
    arcpy.PointsToLine_management(fcSegmentEnds, fcSegmentDistances,
                                  fieldInputID)

    fieldDistance = gis_tools.resetField(fcSegmentDistances, "SgDst", "DOUBLE")
    arcpy.CalculateField_management(fcSegmentDistances, fieldDistance,
                                    "!shape.length!", "PYTHON_9.3")

    # Join straight line distance feature class
    lyrInputTmp = gis_tools.newGISDataset("Layer", "lyrInputTmp")
    arcpy.MakeFeatureLayer_management(fcInputTmp, lyrInputTmp)
    fieldTmpID = gis_tools.resetField(fcSegmentDistances, "TmpID", "DOUBLE")
    arcpy.CalculateField_management(fcSegmentDistances, fieldTmpID,
                                    "!InputID!", "PYTHON_9.3")
    arcpy.AddJoin_management(lyrInputTmp, fieldInputID, fcSegmentDistances,
                             fieldTmpID)

    # Calculate sinuosity
    codeblock = """def calculateSinuosity(length,distance):
        if distance == 0:
            return -9999 
        else:
            return length/distance """
    arcpy.CalculateField_management(
        lyrInputTmp, fieldSinuosity,
        "calculateSinuosity(!{}!, !{}!".format(fieldSegmentLength,
                                               fieldDistance), "PYTHON_9.3",
        codeblock)

    # Write Temporary polyline feature class to disk
    fcOutput = gis_tools.newGISDataset(workspaceTmp,
                                       "outputFCSinuosityChannel")
    arcpy.CopyFeatures_management(lyrInputTmp, fcOutput)

    dropFields = [dropField.name for dropField in arcpy.ListFields(fcOutput)]
    arcpy.MakeTableView_management(fcOutput, "fcOutputView")
    for dropField in dropFields:
        if dropField not in keepFields:
            arcpy.DeleteField_management("fcOutputView", dropField)

    # join final sinuosity output back to input stream network
    arcpy.MakeFeatureLayer_management(fcInput, "lyrInput")
    fcInputOID = arcpy.Describe("lyrInput").OIDFieldName
    arcpy.JoinField_management("lyrInput", fcInputOID, "fcOutputView",
                               "InputID", fieldName)
    return
Esempio n. 11
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
Esempio n. 12
0
def main(source_segments,
         vb_centerline,
         temp_workspace,
         xy_dist=150,
         filterfield="_vb_",
         field_segid="SegmentID",
         out_shapefile=None):
    """ Calculate channel, planform and valley bottom sinuosity"""

    if out_shapefile:
        arcpy.CopyFeatures_management(source_segments, out_shapefile)
        source_segments = out_shapefile
    out_segments = gis_tools.newGISDataset("LAYER", "OutputSegments")

    where = '"{}" = 1'.format(filterfield) if filterfield in arcpy.ListFields(
        source_segments) else None  # TODO Test
    arcpy.MakeFeatureLayer_management(source_segments,
                                      out_segments,
                                      where_clause=where)

    # Generate Split Points
    arcpy.AddMessage("Generating Near Points for Split")
    endpoints = gis_tools.newGISDataset(temp_workspace, "Endpoints")
    arcpy.FeatureVerticesToPoints_management(out_segments, endpoints,
                                             "BOTH_ENDS")
    arcpy.AddXY_management(endpoints)
    arcpy.Near_analysis(endpoints,
                        vb_centerline,
                        location=True,
                        angle=True,
                        method="PLANAR",
                        search_radius=xy_dist)
    sr = arcpy.Describe(endpoints).spatialReference

    ddict_vb_points = defaultdict(list)
    with arcpy.da.SearchCursor(endpoints,
                               ["NEAR_X", "NEAR_Y", field_segid]) as sc:
        splitpoints = [
            arcpy.PointGeometry(arcpy.Point(row[0], row[1]), sr) for row in sc
            if not row[0] == -1
        ]
        sc.reset()
        for row in sc:
            if row[0] != -1:
                ddict_vb_points[row[2]].append(arcpy.Point(row[0], row[1]))

    # Generate Valley Bottom distances
    arcpy.AddMessage("Generating VB Centerline Segment Distances")
    dict_vb_lines = {}
    for segid, lpts in ddict_vb_points.iteritems():
        line = arcpy.Polyline(arcpy.Array(lpts))
        dict_vb_lines[segid] = line
    vb_lines = gis_tools.newGISDataset("in_memory", "VBDIST")
    arcpy.CopyFeatures_management(
        [line for line in dict_vb_lines.itervalues()], vb_lines)

    split_lines = gis_tools.newGISDataset(temp_workspace, "SplitVB_Centerline")
    arcpy.SplitLineAtPoint_management(vb_centerline,
                                      splitpoints,
                                      split_lines,
                                      search_radius=0.1)

    # Selection Polygons from VB_Dist
    arcpy.AddMessage("Generating VB Selection Polygons")
    vb_polys = gis_tools.newGISDataset(temp_workspace, "VB_Polygons")
    arcpy.FeatureToPolygon_management(
        [vb_centerline, vb_lines],
        vb_polys)  # TODO test use vb_centerlines for faster procesing?

    dict_vb_dist = {}
    lyr_selection_polygons = gis_tools.newGISDataset("LAYER",
                                                     "SelectionPolygons")
    arcpy.MakeFeatureLayer_management(vb_polys, lyr_selection_polygons)
    lyr_splitlines = gis_tools.newGISDataset("LAYER", "SplitLines")
    arcpy.MakeFeatureLayer_management(split_lines, lyr_splitlines)
    for segid, vbline in dict_vb_lines.iteritems():
        arcpy.SelectLayerByLocation_management(lyr_selection_polygons,
                                               "SHARE_A_LINE_SEGMENT_WITH",
                                               vbline)
        arcpy.SelectLayerByLocation_management(lyr_splitlines,
                                               "SHARE_A_LINE_SEGMENT_WITH",
                                               lyr_selection_polygons)
        with arcpy.da.SearchCursor(lyr_splitlines,
                                   ["SHAPE@LENGTH"]) as scSplitLines:
            dict_vb_dist[segid] = sum([line[0] for line in scSplitLines])

    # Find Lengths and Distances for Segments
    arcpy.AddMessage("Adding Channel Lengths To Segments")
    field_chanlength = gis_tools.resetField(out_segments, "Chan_Len", "DOUBLE")
    arcpy.CalculateField_management(out_segments, field_chanlength,
                                    "!shape.length!", "PYTHON_9.3")

    # Channel Segment Distances
    arcpy.AddMessage(
        "Adding Channel Distances and VB Lengths and Distances to Segments")
    field_vblength = gis_tools.resetField(out_segments, "VB_Len", "DOUBLE")
    field_chandist = gis_tools.resetField(out_segments, "Chan_Dist", "DOUBLE")
    field_vbdist = gis_tools.resetField(out_segments, "VB_Dist", "DOUBLE")

    total_segments = int(arcpy.GetCount_management(out_segments).getOutput(0))
    percents = [(total_segments / 10) * value for value in range(1, 10, 1)]
    arcpy.AddMessage(
        "Starting iteration of {} segments".format(total_segments))
    with arcpy.da.UpdateCursor(
            out_segments,
        ["SHAPE@", field_vblength, field_chandist, field_vbdist, field_segid
         ]) as ucSegments:
        i = 1
        percent = 0
        for segment in ucSegments:
            segment_endpoints = [
                arcpy.PointGeometry(segment[0].firstPoint),
                arcpy.PointGeometry(segment[0].lastPoint)
            ]
            segment[2] = segment_endpoints[0].distanceTo(segment_endpoints[1])
            segment[3] = dict_vb_lines[
                segment[4]].length if dict_vb_lines.has_key(
                    segment[4]) else 0.0
            segment[1] = dict_vb_dist[segment[4]] if dict_vb_dist.has_key(
                segment[4]) else 0.0
            ucSegments.updateRow(segment)
            if i in percents:
                percent = percent + 10
                arcpy.AddMessage(
                    "   {}% Complete: Segment {} out of {}".format(
                        percent, i, total_segments))
            i = i + 1
        arcpy.AddMessage("  100% Complete: Segment {} out of {}".format(
            total_segments, total_segments))

    # Calculate Sinuosty Metrics
    arcpy.AddMessage("Calculating Sinuosity Values")
    fieldPlanformSinuosity = gis_tools.resetField(out_segments, "Sin_Plan",
                                                  "DOUBLE")
    field_vbsin = gis_tools.resetField(out_segments, "Sin_VB", "DOUBLE")
    field_chansin = gis_tools.resetField(out_segments, "Sin_Chan", "DOUBLE")

    codeblock = """def calculate_sinuosity(seg_length, seg_distance):
        if seg_distance == 0 or seg_distance == -9999:
            return -9999 
        else:
            return seg_length / seg_distance """

    arcpy.CalculateField_management(
        out_segments, fieldPlanformSinuosity,
        "calculate_sinuosity(!{}!, !{}!)".format(field_chanlength,
                                                 field_chandist), "PYTHON_9.3",
        codeblock)
    arcpy.CalculateField_management(
        out_segments, field_chansin,
        "calculate_sinuosity(!{}!, !{}!)".format(field_chanlength,
                                                 field_vblength), "PYTHON_9.3",
        codeblock)
    arcpy.CalculateField_management(
        out_segments, field_vbsin,
        "calculate_sinuosity(!{}!, !{}!)".format(field_vblength, field_vbdist),
        "PYTHON_9.3", codeblock)

    return out_segments
Esempio n. 13
0
def main(fcLineNetwork, fcNetworkNodes, fieldStreamName, fieldStreamOrder,
         fcOutputStreamNetwork, boolDissolve, tempWorkspace):

    reload(gis_tools)

    # Preprocessing
    gis_tools.resetData(fcOutputStreamNetwork)
    listfcMerge = []

    # Check for required attribute fields
    test_field(fcLineNetwork, "GNIS_Name")
    test_field(fcLineNetwork, "_strmordr_")

    # Make Feature Layer for
    lyrStreamSelection = gis_tools.newGISDataset("LAYER",
                                                 "GNAT_BRANCHES_SelectByName")
    arcpy.MakeFeatureLayer_management(fcLineNetwork, lyrStreamSelection)

    # Dissolve by Stream (GNIS) Name
    where = arcpy.AddFieldDelimiters(fcLineNetwork,
                                     fieldStreamName) + " <> '' "
    arcpy.SelectLayerByAttribute_management(lyrStreamSelection,
                                            "NEW_SELECTION", where)
    fcDissolveByName = gis_tools.newGISDataset(tempWorkspace,
                                               "GNAT_BRANCHES_DissolveByName")
    arcpy.Dissolve_management(lyrStreamSelection,
                              fcDissolveByName,
                              fieldStreamName,
                              multi_part="SINGLE_PART",
                              unsplit_lines="DISSOLVE_LINES")
    listfcMerge.append(fcDissolveByName)

    # Select tributary conflences from network nodes
    lyrNetworkNodes = gis_tools.newGISDataset("LAYER",
                                              "GNAT_BRANCHES_NetworkNodes")
    arcpy.MakeFeatureLayer_management(fcNetworkNodes, lyrNetworkNodes)
    fcNodesTC = get_trib_confluences(lyrNetworkNodes)

    # Dissolve by Stream Order
    arcpy.SelectLayerByAttribute_management(lyrStreamSelection,
                                            "SWITCH_SELECTION")

    if fieldStreamOrder:
        if len(arcpy.ListFields(fcLineNetwork, fieldStreamOrder)) == 1:
            fcDissolveByStreamOrder = gis_tools.newGISDataset(
                tempWorkspace, "GNAT_BRANCHES_DissolveByStreamOrder")
            arcpy.Dissolve_management(lyrStreamSelection,
                                      fcDissolveByStreamOrder,
                                      fieldStreamOrder,
                                      multi_part="SINGLE_PART",
                                      unsplit_lines="DISSOLVE_LINES")

    # Split Stream Order Junctions
        if arcpy.Exists(fcNodesTC):
            fcDissolveByStreamOrderSplit = gis_tools.newGISDataset(
                tempWorkspace, "GNAT_BRANCHES_DissolveByStreamOrderSplit")
            arcpy.SplitLineAtPoint_management(fcDissolveByStreamOrder,
                                              fcNodesTC,
                                              fcDissolveByStreamOrderSplit,
                                              "1 METER")
            listfcMerge.append(fcDissolveByStreamOrderSplit)
        else:
            listfcMerge.append(fcDissolveByStreamOrder)
    else:
        fcNoStreamOrder = gis_tools.newGISDataset(
            tempWorkspace, "GNAT_BRANCHES_NoStreamOrderOrStreamName")
        arcpy.Dissolve_management(lyrStreamSelection,
                                  fcNoStreamOrder,
                                  multi_part="SINGLE_PART")
        listfcMerge.append(fcNoStreamOrder)

    # Merge Dissolved Networks
    fcMerged = gis_tools.newGISDataset(
        tempWorkspace, "GNAT_BRANCHES_MergedDissolvedNetworks")
    arcpy.Merge_management(listfcMerge, fcMerged)

    # Add Branch ID
    arcpy.AddField_management(fcMerged, "BranchID", "LONG")
    gis_tools.addUniqueIDField(fcMerged, "BranchID")

    # Final Output
    if boolDissolve == "true":
        arcpy.AddMessage("Dissolving " + str(boolDissolve))
        arcpy.CopyFeatures_management(fcMerged, fcOutputStreamNetwork)
    else:
        ## Delete remaining fields from fcMerged not BranchID, or required fields fieldStreamName,fieldStreamOrder,
        descFCMerged = arcpy.Describe(fcMerged)
        for field in descFCMerged.fields:
            if field.name not in [
                    "BranchID", descFCMerged.OIDFieldName,
                    descFCMerged.shapeFieldName, "Shape_Length"
            ]:
                arcpy.DeleteField_management(fcMerged, field.name)

        arcpy.AddMessage("NOT Dissolving " + str(boolDissolve))
        arcpy.Intersect_analysis([fcMerged, fcLineNetwork],
                                 fcOutputStreamNetwork, "ALL")

    return fcOutputStreamNetwork
Esempio n. 14
0
def main(fcInputSegments,
         fcInputAttrbNetwork,
         tempWorkspace):

    arcpy.env.overwriteOutput = True

    # Turn off Z and M geometry
    arcpy.env.outputMFlag = "Disabled"
    arcpy.env.outputZFlag = "Disabled"

    # Prep temporary files and layers
    arcpy.MakeFeatureLayer_management(fcInputSegments, "lyrInputSegments")
    arcpy.MakeFeatureLayer_management(fcInputAttrbNetwork, "lyrInputAttrbNetwork")
    fcInputAttrbNetworkTemp = gis_tools.newGISDataset(tempWorkspace, "fcInputAttrbNetworkTemp")
    arcpy.CopyFeatures_management("lyrInputAttrbNetwork", fcInputAttrbNetworkTemp)
    fcBraidDslv = gis_tools.newGISDataset(tempWorkspace, "fcBraidDslv")
    fcSegmentDslv = gis_tools.newGISDataset(tempWorkspace, "fcSegmentDslv")
    fcNodeBraidToBraid = gis_tools.newGISDataset(tempWorkspace, "fcNodeBraidToBraid")
    fcNodeBraidToBraidSingle = gis_tools.newGISDataset(tempWorkspace, "fcNodeBraidToBraidSingle")
    fcNodeBraidToBraidDslv = gis_tools.newGISDataset(tempWorkspace, "fcNodeBraidToBraidDslv")
    fcNodeBraidToMainstem = gis_tools.newGISDataset(tempWorkspace, "fcNodeBraidToMainstem")
    fcNodeBraidToMainstemSingle = gis_tools.newGISDataset(tempWorkspace, "fcNodeBraidToMainstemSingle")
    fcNodeBraidToMainstemDslv = gis_tools.newGISDataset(tempWorkspace, "fcNodeBraidToMainstemDslv")
    fcNodeTribConfluence = gis_tools.newGISDataset(tempWorkspace, "fcNodeTribConfluence")
    fcNodeTribConfluenceSingle = gis_tools.newGISDataset(tempWorkspace, "fcNodeTribConfuenceSingle")
    fcNodeTribConfluenceDslv = gis_tools.newGISDataset(tempWorkspace, "fcNodeTribConfluenceDslv")
    fcNodesAll = gis_tools.newGISDataset(tempWorkspace, "fcNodesAll")
    fcNodesToSegments = gis_tools.newGISDataset(tempWorkspace, "fcNodesToSegments")

    # Check if the segmented stream network has a field named LineOID
    if findField(fcInputSegments, "SegmentID"):
        LineOID = "SegmentID"
        pass
    else:
        arcpy.AddMessage("SegmentID attribute field not found in input stream feature class. Using ObjectID field...")
        LineOID = arcpy.Describe(fcInputSegments).OIDFieldName

    # Check if the attributed network as been run through the Generate Network Attributes tool.
    if findField(fcInputAttrbNetworkTemp, "_edgetype_"):
        pass
    else:
        arcpy.AddError("The attributed network input is missing the '_edgetype_' field. Please run the "
                       "network through the Generate Network Attributes tool before running this tool.")

    # Braid-to-braid nodes
    arcpy.AddMessage("GNAT CTT: Generating braid-to-braid nodes...")
    arcpy.MakeFeatureLayer_management(fcInputAttrbNetworkTemp, "lyrInputAttrbNetworkTemp")
    arcpy.SelectLayerByAttribute_management("lyrInputAttrbNetworkTemp","NEW_SELECTION", """ "_edgetype_" = 'braid' """)
    arcpy.Dissolve_management("lyrInputAttrbNetworkTemp", fcBraidDslv, "#", "#", "SINGLE_PART")
    arcpy.Intersect_analysis([fcBraidDslv], fcNodeBraidToBraid, "ONLY_FID", "#", "POINT")
    arcpy.MakeFeatureLayer_management(fcNodeBraidToBraid, "lyrNodeBraidToBraid")
    arcpy.MultipartToSinglepart_management("lyrNodeBraidToBraid", fcNodeBraidToBraidSingle)
    arcpy.MakeFeatureLayer_management(fcNodeBraidToBraidSingle, "lyrNodeBraidToBraidSingle")
    arcpy.Dissolve_management("lyrNodeBraidToBraidSingle", fcNodeBraidToBraidDslv, "#", "#", "SINGLE_PART")
    arcpy.MakeFeatureLayer_management(fcNodeBraidToBraidDslv, "lyrNodeBraidToBraidDslv")
    arcpy.AddField_management("lyrNodeBraidToBraidDslv", "NODE_TYPE", "TEXT")
    arcpy.CalculateField_management("lyrNodeBraidToBraidDslv", "NODE_TYPE", '"BB"', "PYTHON_9.3")

    # Braid-to-mainstem nodes
    arcpy.AddMessage("GNAT CTT: Generating braid-to-mainstem nodes...")
    arcpy.Intersect_analysis([fcBraidDslv,fcInputSegments],fcNodeBraidToMainstem, "#", "#", "POINT")
    arcpy.MakeFeatureLayer_management(fcNodeBraidToMainstem, "lyrNodeBraidToMainstem")
    arcpy.MultipartToSinglepart_management("lyrNodeBraidToMainstem", fcNodeBraidToMainstemSingle)
    arcpy.MakeFeatureLayer_management(fcNodeBraidToMainstemSingle, "lyrNodeBraidToMainstemSingle")
    arcpy.Dissolve_management("lyrNodeBraidToMainstemSingle", fcNodeBraidToMainstemDslv, "#", "#", "SINGLE_PART")
    arcpy.MakeFeatureLayer_management(fcNodeBraidToMainstemDslv, "lyrNodeBraidToMainstemDslv")
    arcpy.AddField_management("lyrNodeBraidToMainstemDslv", "NODE_TYPE", "TEXT")
    arcpy.CalculateField_management("lyrNodeBraidToMainstemDslv", "NODE_TYPE", '"BM"', "PYTHON_9.3")

    # Tributary confluence nodes
    arcpy.AddMessage("GNAT CTT: Generating tributary nodes...")
    arcpy.Dissolve_management("lyrInputSegments", fcSegmentDslv, "#", "#", "SINGLE_PART")
    arcpy.Intersect_analysis([fcSegmentDslv], fcNodeTribConfluence, "ONLY_FID", "#", "POINT")
    arcpy.MakeFeatureLayer_management(fcNodeTribConfluence, "lyrNodeTribConfluence")
    arcpy.MultipartToSinglepart_management("lyrNodeTribConfluence", fcNodeTribConfluenceSingle)
    arcpy.MakeFeatureLayer_management(fcNodeTribConfluenceSingle, "lyrNodeTribConfluenceSingle")
    arcpy.Dissolve_management("lyrNodeTribConfluenceSingle", fcNodeTribConfluenceDslv, "#", "#", "SINGLE_PART")
    arcpy.MakeFeatureLayer_management(fcNodeTribConfluenceDslv, "lyrNodeTribConfluenceDslv")
    arcpy.AddField_management("lyrNodeTribConfluenceDslv", "NODE_TYPE", "TEXT")
    arcpy.CalculateField_management("lyrNodeTribConfluenceDslv", "NODE_TYPE", '"TC"', "PYTHON_9.3")

    # Merge nodes feature classes together
    arcpy.AddMessage("GNAT CTT: Merge and save node feature class...")
    node_list = ["lyrNodeBraidToBraidDslv", "lyrNodeBraidToMainstemDslv", "lyrNodeTribConfluenceDslv"]
    fieldMapping = nodeFieldMap(node_list)
    arcpy.Merge_management(node_list, fcNodesAll, fieldMapping)
    arcpy.MakeFeatureLayer_management(fcNodesAll, "lyrNodesAll")

    # Spatial join nodes to segmented stream network
    arcpy.SpatialJoin_analysis("lyrInputSegments", "lyrNodesAll", fcNodesToSegments, "JOIN_ONE_TO_MANY",
                               "KEEP_COMMON", "#", "INTERSECT")

    # Summarize each node type by attribute field LineOID
    arcpy.AddMessage("GNAT CTT: Summarize nodes per stream segments...")
    arcpy.MakeFeatureLayer_management(fcNodesToSegments, "lyrNodesToSegments")

    # Spatial join each summary table as a new attribute field to final segment network
    node_types = ["BB", "BM", "TC"]
    for n in node_types:
        join_node_summary("lyrInputSegments", n, "lyrNodesToSegments", LineOID, tempWorkspace)

    arcpy.AddMessage("GNAT CTT: Processing complete.")