def determine_banks(fcInputStreamLineNetwork, fcChannelBankPolygons,
                    scratchWorkspace):

    fcChannelBankSideBuffer = gis_tools.newGISDataset(scratchWorkspace,
                                                      "BankSide_Buffer")
    fcChannelBankSidePoints = gis_tools.newGISDataset(scratchWorkspace,
                                                      "BankSidePoints")
    arcpy.Buffer_analysis(fcInputStreamLineNetwork, fcChannelBankSideBuffer,
                          "1 Meter", "LEFT", "FLAT", "NONE")
    arcpy.FeatureToPoint_management(fcChannelBankSideBuffer,
                                    fcChannelBankSidePoints, "INSIDE")
    arcpy.AddField_management(fcChannelBankPolygons, "BankSide", "TEXT", "10")
    lyrChannelBanks = gis_tools.newGISDataset("Layer", "lyrChannelBanks")
    arcpy.MakeFeatureLayer_management(fcChannelBankPolygons, lyrChannelBanks)
    arcpy.SelectLayerByLocation_management(lyrChannelBanks,
                                           "INTERSECT",
                                           fcChannelBankSidePoints,
                                           selection_type="NEW_SELECTION")
    arcpy.CalculateField_management(lyrChannelBanks, "BankSide", "'LEFT'",
                                    "PYTHON")
    arcpy.SelectLayerByAttribute_management(lyrChannelBanks,
                                            "SWITCH_SELECTION")
    arcpy.CalculateField_management(lyrChannelBanks, "BankSide", "'RIGHT'",
                                    "PYTHON")

    return
def integrated_width(fcInLines,
                     fcInPolygons,
                     fcOutLines,
                     strMetricName="",
                     boolSegmentPolygon=False,
                     temp_workspace="in_memory"):

    fcMemLines = gis_tools.newGISDataset(temp_workspace, "lineNetwork")
    arcpy.CopyFeatures_management(fcInLines, fcMemLines)
    fieldLength = gis_tools.resetField(fcMemLines, "IW_Length", "DOUBLE")
    arcpy.CalculateField_management(fcMemLines, fieldLength, "!Shape!.length",
                                    "PYTHON")

    fcMemPolygons = gis_tools.newGISDataset(temp_workspace, 'Polygons')
    if boolSegmentPolygon:
        DividePolygonBySegment.main(fcMemLines,
                                    fcInPolygons,
                                    fcMemPolygons,
                                    temp_workspace,
                                    dblPointDensity=5.0)
    else:
        arcpy.CopyFeatures_management(fcInPolygons, fcMemPolygons)

    fieldPolygonArea = gis_tools.resetField(fcMemPolygons,
                                            strMetricName[0:6] + "Area",
                                            "DOUBLE")
    arcpy.CalculateField_management(fcMemPolygons, fieldPolygonArea,
                                    "!Shape!.area", "PYTHON")

    f_mappings = arcpy.FieldMappings()
    f_mappings.addTable(fcMemLines)
    fmap_area = arcpy.FieldMap()
    fmap_area.addInputField(fcMemPolygons, fieldPolygonArea)

    f_mappings.addFieldMap(fmap_area)

    arcpy.SpatialJoin_analysis(fcMemLines,
                               fcMemPolygons,
                               fcOutLines,
                               "JOIN_ONE_TO_ONE",
                               "KEEP_ALL",
                               field_mapping=f_mappings,
                               match_option="WITHIN")
    fieldIntegratedWidth = gis_tools.resetField(fcOutLines,
                                                "IW" + strMetricName[0:8],
                                                "DOUBLE")
    exp = "!" + fieldPolygonArea + r"! / !" + fieldLength + "!"
    print exp
    arcpy.CalculateField_management(fcOutLines, fieldIntegratedWidth, exp,
                                    "PYTHON_9.3")

    return fieldIntegratedWidth
def transfer_line(fcInLine, fcToLine, strStreamSide):
    outputWorkspace = arcpy.Describe(fcInLine).path
    fcOutput = gis_tools.newGISDataset(
        outputWorkspace, "LineNetworkConfinement" + strStreamSide)

    # Split Line Network by Line Ends
    fcSplitPoints = gis_tools.newGISDataset(
        outputWorkspace, "SplitPoints_Confinement" + strStreamSide)
    arcpy.FeatureVerticesToPoints_management(fcInLine, fcSplitPoints,
                                             "BOTH_ENDS")
    tblNearPointsConfinement = gis_tools.newGISDataset(
        outputWorkspace, "NearPointsConfinement" + strStreamSide)
    arcpy.GenerateNearTable_analysis(fcSplitPoints,
                                     fcToLine,
                                     tblNearPointsConfinement,
                                     location="LOCATION",
                                     angle="ANGLE")
    lyrNearPointsConfinement = gis_tools.newGISDataset(
        "Layer", "lyrNearPointsConfinement" + strStreamSide)
    arcpy.MakeXYEventLayer_management(tblNearPointsConfinement, "NEAR_X",
                                      "NEAR_Y", lyrNearPointsConfinement,
                                      fcToLine)
    arcpy.SplitLineAtPoint_management(fcToLine,
                                      lyrNearPointsConfinement,
                                      fcOutput,
                                      search_radius="0.01 Meters")

    # Prepare Fields
    strConfinementField = "Con_" + strStreamSide
    arcpy.AddField_management(fcOutput, strConfinementField, "LONG")

    # Transfer Attributes by Centroids
    fcCentroidPoints = gis_tools.newGISDataset(
        outputWorkspace, "CentroidPoints_Confinement" + strStreamSide)
    arcpy.FeatureVerticesToPoints_management(fcInLine, fcCentroidPoints, "MID")
    tblNearPointsCentroid = gis_tools.newGISDataset(
        outputWorkspace, "NearPointsCentroid" + strStreamSide)
    arcpy.GenerateNearTable_analysis(fcCentroidPoints,
                                     fcToLine,
                                     tblNearPointsCentroid,
                                     location="LOCATION",
                                     angle="ANGLE")
    lyrNearPointsCentroid = gis_tools.newGISDataset(
        "Layer", "lyrNearPointsCentroid" + strStreamSide)
    arcpy.MakeXYEventLayer_management(tblNearPointsCentroid, "NEAR_X",
                                      "NEAR_Y", lyrNearPointsCentroid,
                                      fcToLine)
    lyrToLineSegments = gis_tools.newGISDataset("Layer", "lyrToLineSegments")
    arcpy.MakeFeatureLayer_management(fcOutput, lyrToLineSegments)

    arcpy.SelectLayerByLocation_management(
        lyrToLineSegments,
        "INTERSECT",
        lyrNearPointsCentroid,
        selection_type="NEW_SELECTION")  #"0.01 Meter","NEW_SELECTION")
    arcpy.CalculateField_management(lyrToLineSegments, strConfinementField, 1,
                                    "PYTHON")

    return fcOutput
Beispiel #4
0
def determine_banks(fcInputStreamLineNetwork, fcChannelBankPolygons,
                    scratchWorkspace):
    '''
        Description:
            Takes  the stream network, buffers out to the left by 1 meter, extracts centroid and
            uses that to select left channel bank (a layer with two polygons l/r), and sets bankside to LEFT
            then inverts selection and set that to RIGHT writing this back to fcChannelBankPolygons.

        Update: 24/8/18 - DDH -Added error trapping
    '''
    try:
        fcChannelBankSideBuffer = gis_tools.newGISDataset(
            scratchWorkspace, "BankSide_Buffer")
        fcChannelBankSidePoints = gis_tools.newGISDataset(
            scratchWorkspace, "BankSidePoints")
        arcpy.Buffer_analysis(fcInputStreamLineNetwork,
                              fcChannelBankSideBuffer, "1 Meter", "LEFT",
                              "FLAT", "NONE")
        arcpy.FeatureToPoint_management(fcChannelBankSideBuffer,
                                        fcChannelBankSidePoints, "INSIDE")
        arcpy.AddField_management(fcChannelBankPolygons, "BankSide", "TEXT",
                                  "10")
        lyrChannelBanks = gis_tools.newGISDataset("Layer", "lyrChannelBanks")
        arcpy.MakeFeatureLayer_management(fcChannelBankPolygons,
                                          lyrChannelBanks)
        arcpy.SelectLayerByLocation_management(lyrChannelBanks,
                                               "INTERSECT",
                                               fcChannelBankSidePoints,
                                               selection_type="NEW_SELECTION")
        arcpy.CalculateField_management(lyrChannelBanks, "BankSide", "'LEFT'",
                                        "PYTHON")
        arcpy.SelectLayerByAttribute_management(lyrChannelBanks,
                                                "SWITCH_SELECTION")
        arcpy.CalculateField_management(lyrChannelBanks, "BankSide", "'RIGHT'",
                                        "PYTHON")
        return
    except Exception as e:
        arcpy.AddError("Error in determine_banks function: " + str(e))
def main(fcFromLine, fcToLine, fcOutputLineNetwork, tempWorkspace):

    gis_tools.resetData(fcOutputLineNetwork)

    fcFromLineTemp = gis_tools.newGISDataset(tempWorkspace,
                                             "GNAT_TLA_FromLineTemp")
    arcpy.MakeFeatureLayer_management(fcFromLine, "lyrFromLine")
    arcpy.CopyFeatures_management("lyrFromLine", fcFromLineTemp)

    # 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")

    # 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(fcFromLineTemp, fcFromLineBuffer, "20 Meters",
                          "FULL", "ROUND", "ALL")
    fcFromLineBufDslv = gis_tools.newGISDataset(tempWorkspace,
                                                "GNAT_TLA_FromLineBUfDslv")
    arcpy.Dissolve_management(fcFromLineBuffer, fcFromLineBufDslv)

    # Select features from "To" line feature class that are inside "From" line buffer
    lyrFromLineBuffer = gis_tools.newGISDataset("Layer", "lyrFromLineBuffer")
    arcpy.MakeFeatureLayer_management(fcFromLineBufDslv, 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
    fcSegmentedBoundingPolygons = gis_tools.newGISDataset(
        tempWorkspace, "GNAT_TLA_SegmentedBoundingPolygons")
    DividePolygonBySegment.main(fcFromLineTemp, fcFromLineBuffer,
                                fcSegmentedBoundingPolygons)

    # Split points of "To" line at intersection of polygon segments
    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.SelectLayerByAttribute_management("lyrOutputLineNetwork",
                                            "NEW_SELECTION",
                                            """"Join_Count" = 0""")
    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
def main(fcInputSegments, fcInputFullNetwork, fcOutputNodes, 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(fcInputFullNetwork,
                                      "lyrInputFullNetwork")
    fcInputFullNetworkTemp = gis_tools.newGISDataset(tempWorkspace,
                                                     "fcInputFullNetworkTemp")
    arcpy.CopyFeatures_management("lyrInputFullNetwork",
                                  fcInputFullNetworkTemp)
    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")
    tblNodeBMSummary = gis_tools.newGISDataset(tempWorkspace,
                                               "tblNodeBMSummary")
    tblNodeTCSummary = gis_tools.newGISDataset(tempWorkspace,
                                               "tblNodeTCSummary")

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

    # Check if the full stream network as been run through the Find Braided Network tool.
    if findField(fcInputFullNetworkTemp, "IsBraided"):
        pass
    else:
        FindBraidedNetwork.main(fcInputFullNetworkTemp)

    # Braid-to-braid nodes
    arcpy.AddMessage("GNAT CTT: Generating braid-to-braid nodes...")
    arcpy.MakeFeatureLayer_management(fcInputFullNetworkTemp,
                                      "lyrInputFullNetworkTemp")
    arcpy.SelectLayerByAttribute_management("lyrInputFullNetworkTemp",
                                            "NEW_SELECTION", '"IsBraided" = 1')
    arcpy.SelectLayerByLocation_management("lyrInputFullNetworkTemp",
                                           "HAVE_THEIR_CENTER_IN",
                                           "lyrInputSegments", "#",
                                           "REMOVE_FROM_SELECTION")
    arcpy.Dissolve_management("lyrInputFullNetworkTemp", 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")
    # Save merged nodes to disk
    arcpy.MakeFeatureLayer_management(fcNodesAll, "lyrNodesAll")
    arcpy.CopyFeatures_management("lyrNodesAll", fcOutputNodes)
    # Summarize each node type by attribute field LineOID
    arcpy.AddMessage("GNAT CTT: Summarize nodes per stream segments...")
    arcpy.MakeFeatureLayer_management(fcNodesToSegments, "lyrNodesToSegments")
    arcpy.SelectLayerByAttribute_management("lyrNodesToSegments",
                                            "NEW_SELECTION",
                                            """"NODE_TYPE" = 'BM'""")
    arcpy.Statistics_analysis("lyrNodesToSegments", tblNodeBMSummary,
                              [["NODE_TYPE", "COUNT"]], LineOID)
    arcpy.SelectLayerByAttribute_management("lyrNodesToSegments",
                                            "CLEAR_SELECTION")
    arcpy.SelectLayerByAttribute_management("lyrNodesToSegments",
                                            "NEW_SELECTION",
                                            """"NODE_TYPE" = 'TC'""")
    arcpy.Statistics_analysis("lyrNodesToSegments", tblNodeTCSummary,
                              [["NODE_TYPE", "COUNT"]], LineOID)
    arcpy.SelectLayerByAttribute_management("lyrNodesToSegments",
                                            "CLEAR_SELECTION")
    # Spatial join each summary table as a new field to final segment network
    arcpy.AddField_management("lyrInputSegments", "NODES_BM", "TEXT")
    arcpy.AddField_management("lyrInputSegments", "NODES_TC", "TEXT")
    arcpy.MakeTableView_management(tblNodeBMSummary, "viewNodeBMSummary")
    arcpy.MakeTableView_management(tblNodeTCSummary, "viewNodeTCSummary")
    arcpy.AddJoin_management("lyrInputSegments", LineOID, "viewNodeBMSummary",
                             LineOID, "KEEP_COMMON")
    arcpy.CalculateField_management("lyrInputSegments", "NODES_BM",
                                    '"!COUNT_NODE_TYPE!"', "PYTHON_9.3")
    arcpy.RemoveJoin_management("lyrInputSegments")
    arcpy.AddJoin_management("lyrInputSegments", LineOID, "viewNodeTCSummary",
                             LineOID, "KEEP_COMMON")
    arcpy.CalculateField_management("lyrInputSegments", "NODES_TC",
                                    '"!COUNT_NODE_TYPE!"', "PYTHON_9.3")
    arcpy.RemoveJoin_management("lyrInputSegments")

    arcpy.AddMessage("GNAT CTT: Processing complete.")
Beispiel #7
0
def main(fcLineNetwork,
         fieldStreamRouteID,
         fieldConfinement,
         fieldConstriction,
         strSeedDistance,
         inputliststrWindowSize,
         outputWorkspace,
         tempWorkspace=arcpy.env.scratchWorkspace):
    """Perform a Moving Window Analysis on a Line Network."""

    liststrWindowSize = inputliststrWindowSize.split(";")

    fcLineNetworkDissolved = gis_tools.newGISDataset(
        tempWorkspace, "GNAT_MWA_LineNetworkDissolved")
    arcpy.Dissolve_management(fcLineNetwork,
                              fcLineNetworkDissolved,
                              fieldStreamRouteID,
                              multi_part=False,
                              unsplit_lines=True)

    listLineGeometries = arcpy.CopyFeatures_management(fcLineNetworkDissolved,
                                                       arcpy.Geometry())

    listWindows = []
    listSeeds = []
    listWindowEvents = []
    listgWindows = []
    intSeedID = 0

    iRoutes = int(
        arcpy.GetCount_management(fcLineNetworkDissolved).getOutput(0))
    arcpy.SetProgressor("step", "Processing Each Route", 0, iRoutes, 1)
    iRoute = 0
    with arcpy.da.SearchCursor(
            fcLineNetworkDissolved,
        ["SHAPE@", fieldStreamRouteID, "SHAPE@LENGTH"]) as scLines:
        for fLine in scLines:  #Loop Through Routes
            arcpy.SetProgressorLabel("Route: " + str(iRoute) +
                                     " Seed Point: " + str(intSeedID))
            arcpy.SetProgressorPosition(iRoute)
            gLine = fLine[0]
            dblSeedPointPosition = float(
                max(liststrWindowSize
                    )) / 2  #Start Seeds at position of largest window
            while dblSeedPointPosition + float(
                    max(liststrWindowSize)) / 2 < fLine[2]:
                arcpy.SetProgressorLabel("Route: " + str(iRoute) +
                                         " Seed Point: " + str(intSeedID))
                gSeedPointPosition = gLine.positionAlongLine(
                    dblSeedPointPosition)
                listSeeds.append([
                    scLines[1], intSeedID, gSeedPointPosition
                ])  #gSeedPointPosition.X,gSeedPointPosition.Y])
                for strWindowSize in liststrWindowSize:
                    dblWindowSize = float(strWindowSize)
                    dblLengthStart = dblSeedPointPosition - dblWindowSize / 2
                    dblLengthEnd = dblSeedPointPosition + dblWindowSize / 2

                    gPointStartLocation = gLine.positionAlongLine(
                        dblLengthStart)
                    gPointEndLocation = gLine.positionAlongLine(dblLengthEnd)
                    gTemp = arcpy.Geometry()
                    listgWindowTemp = arcpy.SplitLineAtPoint_management(
                        gLine, [gPointStartLocation, gPointEndLocation], gTemp,
                        "1 METER")
                    #TODO: Need a better method to select the line here!!
                    for gWindowTemp in listgWindowTemp:
                        if abs(gWindowTemp.length - dblWindowSize) < 10:
                            listgWindows.append([
                                scLines[1], intSeedID, dblWindowSize,
                                gWindowTemp
                            ])
                    # End TODO
                    listWindows.append([
                        scLines[1], intSeedID, dblWindowSize,
                        gPointStartLocation
                    ])
                    listWindows.append([
                        scLines[1], intSeedID, dblWindowSize, gPointEndLocation
                    ])
                    listWindowEvents.append([
                        scLines[1], intSeedID, dblWindowSize, dblLengthStart,
                        dblLengthEnd
                    ])
                dblSeedPointPosition = dblSeedPointPosition + float(
                    strSeedDistance)
                intSeedID = intSeedID + 1
            iRoute = iRoute + 1

    fcSeedPoints = gis_tools.newGISDataset(tempWorkspace,
                                           "GNAT_MWA_SeedPoints")
    fcWindowEndPoints = gis_tools.newGISDataset(tempWorkspace,
                                                "GNAT_MWA_WindowEndPoints")
    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_WindowEndPoints",
                                        "POINT",
                                        spatial_reference=fcLineNetwork)
    arcpy.CreateFeatureclass_management(tempWorkspace,
                                        "GNAT_MWA_WindowLines",
                                        "POLYLINE",
                                        spatial_reference=fcLineNetwork)

    gis_tools.resetField(fcSeedPoints, "RouteID", "LONG")
    gis_tools.resetField(fcSeedPoints, "SeedID", "LONG")

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

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

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

    with arcpy.da.InsertCursor(
            fcWindowEndPoints,
        ["RouteID", "SeedID", "Seg", "SHAPE@XY"]) as icWindowEndPoints:
        for row in listWindows:
            icWindowEndPoints.insertRow(row)

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

    fcIntersected = gis_tools.newGISDataset(
        tempWorkspace, "GNAT_MWA_IntersectWindowAttributes")
    arcpy.Intersect_analysis([fcWindowLines, fcLineNetwork],
                             fcIntersected,
                             "ALL",
                             output_type="LINE")

    # Confinement
    tblSummaryStatisticsConfinement = gis_tools.newGISDataset(
        tempWorkspace, "GNAT_MWA_SummaryStatsTableConfinement")
    arcpy.Statistics_analysis(
        fcIntersected, tblSummaryStatisticsConfinement, "Shape_Length SUM",
        fieldStreamRouteID + ";SeedID;Seg;" + fieldConfinement)

    tblSummaryStatisticsPivot = gis_tools.newGISDataset(
        tempWorkspace, "GNAT_MWA_SummaryStatisticsPivotTable")
    arcpy.PivotTable_management(tblSummaryStatisticsConfinement,
                                "Route;SeedID;Seg", fieldConfinement,
                                "SUM_Shape_Length", tblSummaryStatisticsPivot)

    fieldConfinementValue = gis_tools.resetField(tblSummaryStatisticsPivot,
                                                 "CONF_Value", "DOUBLE")

    if len(arcpy.ListFields(tblSummaryStatisticsPivot,
                            fieldConfinement + "1")) == 0:
        arcpy.AddField_management(tblSummaryStatisticsPivot,
                                  fieldConfinement + "1", "DOUBLE")
    if len(arcpy.ListFields(tblSummaryStatisticsPivot,
                            fieldConfinement + "0")) == 0:
        arcpy.AddField_management(tblSummaryStatisticsPivot,
                                  fieldConfinement + "0", "DOUBLE")

    arcpy.CalculateField_management(
        tblSummaryStatisticsPivot, fieldConfinementValue,
        "!" + fieldConfinement + "1!/(!" + fieldConfinement + "0! + !" +
        fieldConfinement + "1!)", "PYTHON")

    #Pivot Confinement on Segment Size
    tblSummaryStatisticsWindowPivot = gis_tools.newGISDataset(
        tempWorkspace, "GNAT_MWA_SummaryStatisticsWindowPivotTable")
    arcpy.PivotTable_management(tblSummaryStatisticsPivot,
                                fieldStreamRouteID + ";SeedID", "Seg",
                                fieldConfinementValue,
                                tblSummaryStatisticsWindowPivot)

    # Constriction

    tblSummaryStatisticsConstriction = gis_tools.newGISDataset(
        tempWorkspace, "GNAT_MWA_SummaryStatsTableConstriction")
    arcpy.Statistics_analysis(
        fcIntersected, tblSummaryStatisticsConstriction, "Shape_Length SUM",
        fieldStreamRouteID + ";SeedID;Seg;" + fieldConstriction)

    tblSummaryStatisticsPivotConstriction = gis_tools.newGISDataset(
        tempWorkspace, "GNAT_MWA_SummaryStatisticsPivotTableConsriction")
    arcpy.PivotTable_management(tblSummaryStatisticsConstriction,
                                "Route;SeedID;Seg", fieldConstriction,
                                "SUM_Shape_Length",
                                tblSummaryStatisticsPivotConstriction)

    fieldConstrictionValue = gis_tools.resetField(
        tblSummaryStatisticsPivotConstriction, "CNST_Value", "DOUBLE")
    if len(
            arcpy.ListFields(tblSummaryStatisticsConstriction,
                             fieldConstriction + "1")) == 0:
        arcpy.AddField_management(tblSummaryStatisticsConstriction,
                                  fieldConstriction + "1", "DOUBLE")
    if len(
            arcpy.ListFields(tblSummaryStatisticsConstriction,
                             fieldConstriction + "0")) == 0:
        arcpy.AddField_management(tblSummaryStatisticsConstriction,
                                  fieldConstriction + "0", "DOUBLE")

    arcpy.CalculateField_management(
        tblSummaryStatisticsPivotConstriction, fieldConstrictionValue,
        "!" + fieldConstriction + "1!/(!" + fieldConstriction + "0! + !" +
        fieldConstriction + "1!)", "PYTHON")
    tblSummaryStatisticsWindowPivotConstriction = gis_tools.newGISDataset(
        tempWorkspace,
        "GNAT_MWA_SummaryStatisticsWindowPivotTableConstriction")
    arcpy.PivotTable_management(tblSummaryStatisticsPivotConstriction,
                                fieldStreamRouteID + ";SeedID", "Seg",
                                fieldConstrictionValue,
                                tblSummaryStatisticsWindowPivotConstriction)

    strWindowSizeFields = ""
    for WindowSize in liststrWindowSize:
        strWindowSizeFields = strWindowSizeFields + ";Seg" + WindowSize
    strWindowSizeFields = strWindowSizeFields.lstrip(";")

    #Join Above table to seed points
    arcpy.JoinField_management(fcSeedPoints, "SeedID",
                               tblSummaryStatisticsWindowPivot, "SeedID",
                               strWindowSizeFields)
    arcpy.JoinField_management(fcSeedPoints, "SeedID",
                               tblSummaryStatisticsWindowPivotConstriction,
                               "SeedID", strWindowSizeFields)

    # Manage Outputs
    fcOutputSeedPoints = gis_tools.newGISDataset(outputWorkspace,
                                                 "MovingWindowSeedPoints")
    arcpy.CopyFeatures_management(fcSeedPoints, fcOutputSeedPoints)

    fcOutputWindows = gis_tools.newGISDataset(outputWorkspace,
                                              "MovingWindowSegments")
    arcpy.CopyFeatures_management(fcWindowLines, fcOutputWindows)

    return
def main(fcInputCenterline,
         fcInputPolygon,
         fcSegmentedPolygons,
         workspaceTemp,
         dblPointDensity=10.0,
         dblJunctionBuffer=120.00):

    arcpy.AddMessage("GNAT Divide Polygon By Segment Tool")
    arcpy.AddMessage("GNAT DPS: Saving Polygon Results to: " +
                     fcSegmentedPolygons)
    arcpy.AddMessage("GNAT DPS: Saving Temporary Files to: " + workspaceTemp)

    arcpy.env.OutputMFlag = "Disabled"
    arcpy.env.OutputZFlag = "Disabled"

    arcpy.AddMessage("arcpy M Output Flag: " + str(arcpy.env.OutputMFlag))

    ## Copy Centerline to Temp Workspace
    fcCenterline = gis_tools.newGISDataset(workspaceTemp,
                                           "GNAT_DPS_Centerline")
    arcpy.CopyFeatures_management(fcInputCenterline, fcCenterline)

    ## Build Thiessan Polygons
    arcpy.AddMessage("GNAT DPS: Building Thiessan Polygons")
    arcpy.env.extent = fcInputPolygon  ## Set full extent to build Thiessan polygons over entire line network.
    arcpy.Densify_edit(fcCenterline, "DISTANCE",
                       str(dblPointDensity) + " METERS")

    fcTribJunctionPoints = gis_tools.newGISDataset(
        workspaceTemp,
        "GNAT_DPS_TribJunctionPoints")  # All Segment Junctions??
    #gis_tools.findSegmentJunctions(fcCenterline,fcTribJunctionPoints,"ALL")
    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,
                                           str(dblJunctionBuffer) + " METERS",
                                           "NEW_SELECTION")

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

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

    ### Code to Split the Junction Thiessan Polys ###
    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,
                                           selection_type="NEW_SELECTION")

    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 Polys 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,
                              "JOIN_FID",
                              multi_part="SINGLE_PART")

    #fcSegmentedPolygons = gis_tools.newGISDataset(workspaceOutput,"SegmentedPolygons")
    lyrPolygonsDissolved = gis_tools.newGISDataset("Layer",
                                                   "lyrPolygonsDissolved")
    arcpy.MakeFeatureLayer_management(fcPolygonsDissolved,
                                      lyrPolygonsDissolved)
    arcpy.SelectLayerByAttribute_management(lyrPolygonsDissolved,
                                            "NEW_SELECTION",
                                            """ "JOIN_FID" = -1 """)

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

    arcpy.AddMessage("GNAT DPS: Tool Complete.")
    return
def main(fcLineNetwork, fcSplitPoints, fieldStreamName, fieldStreamOrder,
         fcOutputStreamNetwork, boolDissolve, tempWorkspace):

    reload(gis_tools)

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

    # 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)
    arcpy.Dissolve_management(lyrStreamSelection,
                              fcDissolveByName,
                              fieldStreamName,
                              multi_part="SINGLE_PART",
                              unsplit_lines="DISSOLVE_LINES")
    listfcMerge.append(fcDissolveByName)

    # 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)

    # Split Stream Order Junctions
        if arcpy.Exists(fcSplitPoints):
            fcDissolveByStreamOrderSplit = gis_tools.newGISDataset(
                tempWorkspace, "GNAT_BRANCHES_DissolveByStreamOrderSplit")
            arcpy.SplitLineAtPoint_management(fcDissolveByStreamOrder,
                                              fcSplitPoints,
                                              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
Beispiel #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(!" +
        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
Beispiel #11
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
def main(fcInputStreamLineNetwork,
         fcInputValleyBottomPolygon,
         fcInputChannelPolygon,
         fcOutputRawConfiningState,
         fcOutputConfiningMargins,
         scratchWorkspace,
         boolIntegratedWidthAttributes=False):

    ##Prepare processing environments
    arcpy.AddMessage("Starting Confining Margins Tool")

    # Create Confined Channel Polygon
    fcConfinedChannel = gis_tools.newGISDataset(scratchWorkspace,
                                                "ChannelConfined")
    arcpy.Clip_analysis(fcInputChannelPolygon, fcInputValleyBottomPolygon,
                        fcConfinedChannel)

    # Convert Confined Channel polygon to Edges polyline
    fcChannelMargins = gis_tools.newGISDataset(scratchWorkspace,
                                               "ChannelMargins")
    arcpy.PolygonToLine_management(fcConfinedChannel, fcChannelMargins)

    # Create Confinement Edges
    if fcOutputConfiningMargins:
        gis_tools.resetData(fcOutputConfiningMargins)
        fcConfiningMargins = fcOutputConfiningMargins
    else:
        fcConfiningMargins = gis_tools.newGISDataset(scratchWorkspace,
                                                     "ConfiningMargins")

    fcConfiningMarginsMultipart = gis_tools.newGISDataset(
        scratchWorkspace, "ConfiningMargins_Multipart")
    arcpy.Intersect_analysis([fcConfinedChannel, fcInputValleyBottomPolygon],
                             fcConfiningMarginsMultipart,
                             output_type="LINE")
    arcpy.MultipartToSinglepart_management(fcConfiningMarginsMultipart,
                                           fcConfiningMargins)

    # Merge segments in Polyline Center to create Route Layer
    arcpy.env.outputZFlag = "Disabled"  # 'empty' z values can cause problem with dissolve
    fcStreamNetworkDissolved = gis_tools.newGISDataset(
        scratchWorkspace, "StreamNetworkDissolved"
    )  # one feature per 'section between trib or branch junctions'
    arcpy.Dissolve_management(fcInputStreamLineNetwork,
                              fcStreamNetworkDissolved,
                              multi_part="SINGLE_PART",
                              unsplit_lines="UNSPLIT_LINES")

    fcNetworkSegmentPoints = gis_tools.newGISDataset(
        scratchWorkspace, "StreamNetworkSegmentPoints")
    arcpy.FeatureVerticesToPoints_management(fcInputStreamLineNetwork,
                                             fcNetworkSegmentPoints, "END")
    fcStreamNetworkDangles = gis_tools.newGISDataset(scratchWorkspace,
                                                     "StreamNetworkDangles")
    arcpy.FeatureVerticesToPoints_management(fcInputStreamLineNetwork,
                                             fcStreamNetworkDangles, "DANGLE")

    #SegmentPolgyons
    arcpy.AddMessage("Preparing Segmented Polygons...")

    fcChannelSegmentPolygons = gis_tools.newGISDataset(scratchWorkspace,
                                                       "SegmentPolygons")
    fcChannelSegmentPolygonLines = gis_tools.newGISDataset(
        scratchWorkspace, "SegmentPolygonLines")

    #DividePolygonBySegment.main(fcInputStreamLineNetwork, fcConfinedChannel, fcChannelSegmentPolygons, scratchWorkspace)
    arcpy.CopyFeatures_management(fcConfinedChannel, fcChannelSegmentPolygons)
    arcpy.PolygonToLine_management(fcChannelSegmentPolygons,
                                   fcChannelSegmentPolygonLines)

    lyrStreamNetworkDangles = gis_tools.newGISDataset(
        "LAYER", "lyrStreamNetworkDangles")
    arcpy.MakeFeatureLayer_management(fcStreamNetworkDangles,
                                      lyrStreamNetworkDangles)
    arcpy.SelectLayerByLocation_management(lyrStreamNetworkDangles,
                                           "INTERSECT", fcConfinedChannel)
    arcpy.Near_analysis(lyrStreamNetworkDangles,
                        fcChannelSegmentPolygonLines,
                        location="LOCATION")

    arcpy.AddXY_management(lyrStreamNetworkDangles)

    fcChannelBankNearLines = gis_tools.newGISDataset(scratchWorkspace,
                                                     "Bank_NearLines")
    arcpy.XYToLine_management(lyrStreamNetworkDangles, fcChannelBankNearLines,
                              "POINT_X", "POINT_Y", "NEAR_X", "NEAR_Y")

    fcChannelBankLines = gis_tools.newGISDataset(scratchWorkspace,
                                                 "Bank_Lines")
    arcpy.Merge_management([
        fcInputStreamLineNetwork, fcChannelBankNearLines,
        fcChannelSegmentPolygonLines
    ], fcChannelBankLines)
    fcChannelBankPolygons = gis_tools.newGISDataset(scratchWorkspace,
                                                    "Bank_Polygons")
    arcpy.FeatureToPolygon_management(fcChannelBankLines,
                                      fcChannelBankPolygons)

    # # Intersect and Split Channel polygon Channel Edges and Polyline Confinement using cross section lines
    arcpy.AddMessage("Intersect and Split Channel Polygons...")
    fcIntersectPoints_ChannelMargins = gis_tools.newGISDataset(
        scratchWorkspace, "IntersectPoints_ChannelMargins")
    fcIntersectPoints_ConfinementMargins = gis_tools.newGISDataset(
        scratchWorkspace, "IntersectPoints_ConfinementMargins")
    arcpy.Intersect_analysis(
        [fcConfiningMargins, fcChannelSegmentPolygonLines],
        fcIntersectPoints_ConfinementMargins,
        output_type="POINT")
    arcpy.Intersect_analysis([fcChannelMargins, fcChannelSegmentPolygonLines],
                             fcIntersectPoints_ChannelMargins,
                             output_type="POINT")
    fcConfinementMargin_Segments = gis_tools.newGISDataset(
        scratchWorkspace, "ConfinementMargin_Segments")
    fcChannelMargin_Segments = gis_tools.newGISDataset(
        scratchWorkspace, "ChannelMargin_Segements")
    arcpy.SplitLineAtPoint_management(fcConfiningMargins,
                                      fcIntersectPoints_ConfinementMargins,
                                      fcConfinementMargin_Segments,
                                      search_radius="10 Meters")
    arcpy.SplitLineAtPoint_management(fcChannelMargins,
                                      fcIntersectPoints_ChannelMargins,
                                      fcChannelMargin_Segments,
                                      search_radius="10 Meters")

    # Create River Side buffer to select right or left banks
    arcpy.AddMessage("Determining Relative Sides of Bank...")
    determine_banks(fcInputStreamLineNetwork, fcChannelBankPolygons,
                    scratchWorkspace)

    # Prepare Layers for Segment Selection
    lyrSegmentPolygons = gis_tools.newGISDataset("Layer", "lyrSegmentPolygons")
    lyrConfinementEdgeSegments = gis_tools.newGISDataset(
        "Layer", "lyrConfinementEdgeSegments")
    lyrChannelEdgeSegments = gis_tools.newGISDataset("Layer",
                                                     "lyrChannelEdgeSegments")
    arcpy.MakeFeatureLayer_management(fcChannelSegmentPolygons,
                                      lyrSegmentPolygons)
    arcpy.MakeFeatureLayer_management(fcConfinementMargin_Segments,
                                      lyrConfinementEdgeSegments)
    arcpy.MakeFeatureLayer_management(fcChannelMargin_Segments,
                                      lyrChannelEdgeSegments)

    ## Prepare Filtered Margins
    fcFilterSplitPoints = gis_tools.newGISDataset(scratchWorkspace,
                                                  "FilterSplitPoints")
    arcpy.FeatureVerticesToPoints_management(fcConfinementMargin_Segments,
                                             fcFilterSplitPoints, "BOTH_ENDS")

    # Transfer Confining Margins to Stream Network ##
    arcpy.AddMessage("Transferring Confining Margins to Stream Network...")
    fcConfinementMarginSegmentsBankSide = gis_tools.newGISDataset(
        scratchWorkspace, "ConfinementMarginSegmentsBank")
    lyrConfinementMarginSegmentsBankside = gis_tools.newGISDataset(
        "Layer", "lyrConfinementMarginSegmentsBankside")

    field_map = """BankSide "BankSide" true true false 255 Text 0 0 ,First,#,""" + fcChannelBankPolygons + """,BankSide,-1,-1"""
    arcpy.SpatialJoin_analysis(fcConfinementMargin_Segments,
                               fcChannelBankPolygons,
                               fcConfinementMarginSegmentsBankSide,
                               "JOIN_ONE_TO_ONE", "KEEP_ALL", field_map)

    arcpy.MakeFeatureLayer_management(fcConfinementMarginSegmentsBankSide,
                                      lyrConfinementMarginSegmentsBankside)
    arcpy.SelectLayerByAttribute_management(
        lyrConfinementMarginSegmentsBankside, "NEW_SELECTION",
        """ "BankSide" = 'LEFT'""")

    fcStreamNetworkConfinementLeft = transfer_line(
        lyrConfinementMarginSegmentsBankside, fcStreamNetworkDissolved, "LEFT")
    arcpy.SelectLayerByAttribute_management(
        lyrConfinementMarginSegmentsBankside, "NEW_SELECTION",
        """ "BankSide" = 'RIGHT'""")
    fcStreamNetworkConfinementRight = transfer_line(
        lyrConfinementMarginSegmentsBankside, fcStreamNetworkDissolved,
        "RIGHT")

    fcConfinementStreamNetworkIntersected = gis_tools.newGISDataset(
        scratchWorkspace, "ConfinementStreamNetworkIntersected")
    arcpy.Intersect_analysis(
        [fcStreamNetworkConfinementLeft, fcStreamNetworkConfinementRight],
        fcConfinementStreamNetworkIntersected, "NO_FID")  # TODO no fid?

    #Re-split centerline by segments
    arcpy.AddMessage("Determining Confinement State on Stream Network...")
    fcRawConfiningNetworkSplit = gis_tools.newGISDataset(
        scratchWorkspace, "RawConfiningNetworkSplit")
    arcpy.SplitLineAtPoint_management(fcConfinementStreamNetworkIntersected,
                                      fcNetworkSegmentPoints,
                                      fcRawConfiningNetworkSplit,
                                      "0.01 Meters")

    #Table and Attributes
    arcpy.AddField_management(fcRawConfiningNetworkSplit,
                              "Con_Type",
                              "TEXT",
                              field_length="6")
    arcpy.AddField_management(fcRawConfiningNetworkSplit, "IsConfined",
                              "SHORT")
    gis_tools.resetField(fcRawConfiningNetworkSplit, "IsConstric", "SHORT")

    lyrRawConfiningNetwork = gis_tools.newGISDataset(
        "Layer", "lyrStreamNetworkCenterline1")
    arcpy.MakeFeatureLayer_management(fcRawConfiningNetworkSplit,
                                      lyrRawConfiningNetwork)

    arcpy.SelectLayerByAttribute_management(lyrRawConfiningNetwork,
                                            "NEW_SELECTION",
                                            """ "Con_LEFT" = 1""")
    arcpy.CalculateField_management(lyrRawConfiningNetwork, "Con_Type",
                                    "'LEFT'", "PYTHON")
    arcpy.SelectLayerByAttribute_management(lyrRawConfiningNetwork,
                                            "NEW_SELECTION",
                                            """ "Con_RIGHT" = 1""")
    arcpy.CalculateField_management(lyrRawConfiningNetwork, "Con_Type",
                                    "'RIGHT'", "PYTHON")
    arcpy.SelectLayerByAttribute_management(
        lyrRawConfiningNetwork, "NEW_SELECTION",
        """ "Con_LEFT" = 1 AND "Con_RIGHT" = 1""")
    arcpy.CalculateField_management(lyrRawConfiningNetwork, "Con_Type",
                                    "'BOTH'", "PYTHON")
    arcpy.CalculateField_management(lyrRawConfiningNetwork, "IsConstric", "1",
                                    "PYTHON")
    arcpy.SelectLayerByAttribute_management(lyrRawConfiningNetwork,
                                            "SWITCH_SELECTION")
    arcpy.CalculateField_management(lyrRawConfiningNetwork, "IsConstric", "0",
                                    "PYTHON")
    arcpy.SelectLayerByAttribute_management(
        lyrRawConfiningNetwork, "NEW_SELECTION",
        """ "Con_LEFT" = 1 OR "Con_RIGHT" = 1""")
    arcpy.CalculateField_management(lyrRawConfiningNetwork, "IsConfined", "1",
                                    "PYTHON")
    arcpy.SelectLayerByAttribute_management(lyrRawConfiningNetwork,
                                            "SWITCH_SELECTION")
    arcpy.CalculateField_management(lyrRawConfiningNetwork, "IsConfined", "0",
                                    "PYTHON")
    arcpy.CalculateField_management(lyrRawConfiningNetwork, "Con_Type",
                                    "'NONE'", "PYTHON")

    # Integrated Width

    fcIntersectLineNetwork = fcInputStreamLineNetwork
    if boolIntegratedWidthAttributes:
        fcIntegratedChannelWidth = gis_tools.newGISDataset(
            scratchWorkspace, "IW_Channel")
        fieldIWChannel = integrated_width(fcInputStreamLineNetwork,
                                          fcChannelSegmentPolygons,
                                          fcIntegratedChannelWidth, "Channel",
                                          False)

        fcIntegratedWidth = gis_tools.newGISDataset(scratchWorkspace,
                                                    "IW_ChannelAndValley")
        fieldIWValley = integrated_width(fcIntegratedChannelWidth,
                                         fcInputValleyBottomPolygon,
                                         fcIntegratedWidth, "Valley", True)

        fieldIWRatio = gis_tools.resetField(fcIntegratedWidth, "IW_Ratio",
                                            "DOUBLE")
        exp = "!" + fieldIWValley + r"! / !" + fieldIWChannel + "!"
        arcpy.CalculateField_management(fcIntegratedWidth, fieldIWRatio, exp,
                                        "PYTHON_9.3")
        fcIntersectLineNetwork = fcIntegratedWidth

    # Final Output
    arcpy.AddMessage("Preparing Final Output...")
    if arcpy.Exists(fcOutputRawConfiningState):
        arcpy.Delete_management(fcOutputRawConfiningState)
    arcpy.Intersect_analysis(
        [fcRawConfiningNetworkSplit, fcIntersectLineNetwork],
        fcOutputRawConfiningState, "NO_FID")

    return
Beispiel #13
0
def transfer_line(fcInLine, fcToLine, strStreamSide):
    '''
    Inputs:
        fcInLine - Confinement margin segments with a selection imposed upon it
        fcToLine - The dissolved river network
        strStreamSide - LEFT or RIGHT
    Outputs:
        fcOutput - Featureclass type line, the network split

        Update: 24/8/18 - DDH -Added error trapping
    '''

    try:
        outputWorkspace = arcpy.Describe(fcInLine).path
        fcOutput = gis_tools.newGISDataset(
            outputWorkspace, "LineNetworkConfinement" + strStreamSide)

        # Split Line Network by Line Ends
        arcpy.AddMessage("... Splitting network")
        fcSplitPoints = gis_tools.newGISDataset(
            outputWorkspace, "SplitPoints_Confinement" + strStreamSide)
        arcpy.FeatureVerticesToPoints_management(fcInLine, fcSplitPoints,
                                                 "BOTH_ENDS")
        tblNearPointsConfinement = gis_tools.newGISDataset(
            outputWorkspace, "NearPointsConfinement" + strStreamSide)
        arcpy.GenerateNearTable_analysis(fcSplitPoints,
                                         fcToLine,
                                         tblNearPointsConfinement,
                                         location="LOCATION",
                                         angle="ANGLE")
        lyrNearPointsConfinement = gis_tools.newGISDataset(
            "Layer", "lyrNearPointsConfinement" + strStreamSide)
        arcpy.MakeXYEventLayer_management(tblNearPointsConfinement, "NEAR_X",
                                          "NEAR_Y", lyrNearPointsConfinement,
                                          fcToLine)
        arcpy.SplitLineAtPoint_management(fcToLine,
                                          lyrNearPointsConfinement,
                                          fcOutput,
                                          search_radius="0.01 Meters")

        # Prepare Fields
        strConfinementField = "Con_" + strStreamSide
        arcpy.AddField_management(fcOutput, strConfinementField, "LONG")

        # Transfer Attributes by Centroids
        arcpy.AddMessage("... Updating Con_" + strStreamSide)
        fcCentroidPoints = gis_tools.newGISDataset(
            outputWorkspace, "CentroidPoints_Confinement" + strStreamSide)
        arcpy.FeatureVerticesToPoints_management(fcInLine, fcCentroidPoints,
                                                 "MID")
        tblNearPointsCentroid = gis_tools.newGISDataset(
            outputWorkspace, "NearPointsCentroid" + strStreamSide)
        arcpy.GenerateNearTable_analysis(fcCentroidPoints,
                                         fcToLine,
                                         tblNearPointsCentroid,
                                         location="LOCATION",
                                         angle="ANGLE")
        lyrNearPointsCentroid = gis_tools.newGISDataset(
            "Layer", "lyrNearPointsCentroid" + strStreamSide)
        arcpy.MakeXYEventLayer_management(tblNearPointsCentroid, "NEAR_X",
                                          "NEAR_Y", lyrNearPointsCentroid,
                                          fcToLine)
        lyrToLineSegments = gis_tools.newGISDataset("Layer",
                                                    "lyrToLineSegments")
        arcpy.MakeFeatureLayer_management(fcOutput, lyrToLineSegments)

        arcpy.SelectLayerByLocation_management(
            lyrToLineSegments,
            "INTERSECT",
            lyrNearPointsCentroid,
            selection_type="NEW_SELECTION")  #"0.01 Meter","NEW_SELECTION")
        arcpy.CalculateField_management(lyrToLineSegments, strConfinementField,
                                        1, "PYTHON")

        bOK = postFIXtoConfinement(fcOutput, strStreamSide,
                                   lyrNearPointsConfinement, fcSplitPoints)
        if not bOK:
            arcpy.AddWarning(
                "The post fix confinement code returned an error, centreline will be attributed incorrectly"
            )
        return fcOutput
    except Exception as e:
        arcpy.AddError("Error in transfer_line function: " + str(e))
Beispiel #14
0
def main(fcInputStreamLineNetwork,
         fcInputValleyBottomPolygon,
         fcInputChannelPolygon,
         filterByLength,
         fcOutputRawConfiningState,
         fcOutputConfiningMargins,
         scratchWorkspace,
         boolIntegratedWidthAttributes=False):
    '''
        Description:
            Main processing function for creating the confinement margins and segmenting the network.

        Updated: 24/8/18 - DDH - Now returns True/False if code succeeds or fails, this can be used by calling module
                  5/9/18 - DDH - Now uses FilterByLength to delete out confinement margins created by the intersection that fall below
                                 the specified length. Default is 5m
                  6/9/18 - DDH - Creates MarginID field and purges out all other fields except Length
    '''
    try:

        ##Prepare processing environments
        arcpy.AddMessage("Starting Confining Margins Tool")

        # Create Confined Channel Polygon
        # This clips the channel polygon by the valley botton polygon
        arcpy.AddMessage("... Clipping channel polygon with Valley bottom")
        fcConfinedChannel = gis_tools.newGISDataset(scratchWorkspace,
                                                    "ChannelConfined")
        arcpy.Clip_analysis(fcInputChannelPolygon, fcInputValleyBottomPolygon,
                            fcConfinedChannel)

        # Convert Confined Channel polygon to Edges polyline
        arcpy.AddMessage(
            "... Converting clipped channel polygon to a polyline dataset")
        fcChannelMargins = gis_tools.newGISDataset(scratchWorkspace,
                                                   "ChannelMargins")
        arcpy.PolygonToLine_management(fcConfinedChannel, fcChannelMargins)

        # Create Confinement Edges
        if fcOutputConfiningMargins:
            gis_tools.resetData(fcOutputConfiningMargins)
            fcConfiningMargins = fcOutputConfiningMargins
        else:
            fcConfiningMargins = gis_tools.newGISDataset(
                scratchWorkspace, "ConfiningMargins")

        arcpy.AddMessage(
            "... Intersecting clipped channel polygon with valley bottom returning intersection lines"
        )
        fcConfiningMarginsMultipart = gis_tools.newGISDataset(
            scratchWorkspace, "ConfiningMargins_Multipart")
        arcpy.Intersect_analysis(
            [fcConfinedChannel, fcInputValleyBottomPolygon],
            fcConfiningMarginsMultipart,
            output_type="LINE")
        arcpy.MultipartToSinglepart_management(fcConfiningMarginsMultipart,
                                               fcConfiningMargins)

        # Delete lines that fall below the specified length
        if filterByLength > 0:
            # Make a temporary layer, select lines and delete
            arcpy.AddMessage("... Adding Length field and updating")
            arcpy.MakeFeatureLayer_management(fcConfiningMargins, "tempLayer")
            arcpy.AddField_management("tempLayer", "Length", "DOUBLE")
            arcpy.CalculateField_management("tempLayer", "Length",
                                            "!SHAPE.length@METERS!",
                                            "PYTHON_9.3")
            arcpy.AddMessage("... Selecting lines smaller than " +
                             str(filterByLength) + "m and deleting")
            arcpy.SelectLayerByAttribute_management(
                "tempLayer", "NEW_SELECTION",
                '"' + "Length" + '"' + " <= " + str(filterByLength))
            descObj = arcpy.Describe("tempLayer")
            if len(descObj.FIDSet) > 0:
                # A Selection exists so delete
                arcpy.DeleteFeatures_management("tempLayer")

            # Clean up
            del descObj
            arcpy.Delete_management("tempLayer")
        else:
            arcpy.AddMessage(
                "Filter by Length parameter was set to 0m, skipping deleting features"
            )

        # Merge segments in Polyline Centerline to create Route Layer
        arcpy.AddMessage("... Dissolving stream network into routes")
        arcpy.env.outputZFlag = "Disabled"  # 'empty' z values can cause problem with dissolve
        fcStreamNetworkDissolved = gis_tools.newGISDataset(
            scratchWorkspace, "StreamNetworkDissolved"
        )  # one feature per 'section between trib or branch junctions'
        arcpy.Dissolve_management(fcInputStreamLineNetwork,
                                  fcStreamNetworkDissolved,
                                  multi_part="SINGLE_PART",
                                  unsplit_lines="UNSPLIT_LINES")

        arcpy.AddMessage("... Extracting stream network END points")
        fcNetworkSegmentPoints = gis_tools.newGISDataset(
            scratchWorkspace, "StreamNetworkSegmentPoints")
        arcpy.FeatureVerticesToPoints_management(fcInputStreamLineNetwork,
                                                 fcNetworkSegmentPoints, "END")

        arcpy.AddMessage("... Extracting stream network DANGLE points")
        fcStreamNetworkDangles = gis_tools.newGISDataset(
            scratchWorkspace, "StreamNetworkDangles")
        arcpy.FeatureVerticesToPoints_management(fcInputStreamLineNetwork,
                                                 fcStreamNetworkDangles,
                                                 "DANGLE")

        #SegmentPolgyons
        arcpy.AddMessage("Preparing Segmented Polygons...")

        fcChannelSegmentPolygons = gis_tools.newGISDataset(
            scratchWorkspace, "SegmentPolygons")
        fcChannelSegmentPolygonLines = gis_tools.newGISDataset(
            scratchWorkspace, "SegmentPolygonLines")

        arcpy.AddMessage(
            "... Copying clipped channel polygon and converting to polyline dataset"
        )
        #DividePolygonBySegment.main(fcInputStreamLineNetwork, fcConfinedChannel, fcChannelSegmentPolygons, scratchWorkspace)
        arcpy.CopyFeatures_management(fcConfinedChannel,
                                      fcChannelSegmentPolygons)
        arcpy.PolygonToLine_management(fcChannelSegmentPolygons,
                                       fcChannelSegmentPolygonLines)

        arcpy.AddMessage("... Building proximity information for DANGLES")
        lyrStreamNetworkDangles = gis_tools.newGISDataset(
            "LAYER", "lyrStreamNetworkDangles")
        arcpy.MakeFeatureLayer_management(fcStreamNetworkDangles,
                                          lyrStreamNetworkDangles)
        arcpy.SelectLayerByLocation_management(lyrStreamNetworkDangles,
                                               "INTERSECT", fcConfinedChannel)
        arcpy.Near_analysis(lyrStreamNetworkDangles,
                            fcChannelSegmentPolygonLines,
                            location="LOCATION")
        arcpy.AddXY_management(lyrStreamNetworkDangles)

        arcpy.AddMessage("... Building bank lines")
        fcChannelBankNearLines = gis_tools.newGISDataset(
            scratchWorkspace, "Bank_NearLines")
        arcpy.XYToLine_management(lyrStreamNetworkDangles,
                                  fcChannelBankNearLines, "POINT_X", "POINT_Y",
                                  "NEAR_X", "NEAR_Y")

        fcChannelBankLines = gis_tools.newGISDataset(scratchWorkspace,
                                                     "Bank_Lines")
        arcpy.Merge_management([
            fcInputStreamLineNetwork, fcChannelBankNearLines,
            fcChannelSegmentPolygonLines
        ], fcChannelBankLines)
        fcChannelBankPolygons = gis_tools.newGISDataset(
            scratchWorkspace, "Bank_Polygons")
        arcpy.FeatureToPolygon_management(fcChannelBankLines,
                                          fcChannelBankPolygons)

        # Intersect and Split Channel polygon Channel Edges and Polyline Confinement using cross section lines
        arcpy.AddMessage("Intersect and Split Channel Polygons...")
        fcIntersectPoints_ChannelMargins = gis_tools.newGISDataset(
            scratchWorkspace, "IntersectPoints_ChannelMargins")
        fcIntersectPoints_ConfinementMargins = gis_tools.newGISDataset(
            scratchWorkspace, "IntersectPoints_ConfinementMargins")
        arcpy.Intersect_analysis(
            [fcConfiningMargins, fcChannelSegmentPolygonLines],
            fcIntersectPoints_ConfinementMargins,
            output_type="POINT")
        arcpy.Intersect_analysis(
            [fcChannelMargins, fcChannelSegmentPolygonLines],
            fcIntersectPoints_ChannelMargins,
            output_type="POINT")
        fcConfinementMargin_Segments = gis_tools.newGISDataset(
            scratchWorkspace, "ConfinementMargin_Segments")
        fcChannelMargin_Segments = gis_tools.newGISDataset(
            scratchWorkspace, "ChannelMargin_Segements")
        arcpy.SplitLineAtPoint_management(fcConfiningMargins,
                                          fcIntersectPoints_ConfinementMargins,
                                          fcConfinementMargin_Segments,
                                          search_radius="10 Meters")
        arcpy.SplitLineAtPoint_management(fcChannelMargins,
                                          fcIntersectPoints_ChannelMargins,
                                          fcChannelMargin_Segments,
                                          search_radius="10 Meters")

        # Create River Side buffer to select right or left banks
        arcpy.AddMessage("Determining Relative Sides of Bank...")
        determine_banks(fcInputStreamLineNetwork, fcChannelBankPolygons,
                        scratchWorkspace)

        # Prepare Layers for Segment Selection
        lyrSegmentPolygons = gis_tools.newGISDataset("Layer",
                                                     "lyrSegmentPolygons")
        lyrConfinementEdgeSegments = gis_tools.newGISDataset(
            "Layer", "lyrConfinementEdgeSegments")
        lyrChannelEdgeSegments = gis_tools.newGISDataset(
            "Layer", "lyrChannelEdgeSegments")
        arcpy.MakeFeatureLayer_management(fcChannelSegmentPolygons,
                                          lyrSegmentPolygons)
        arcpy.MakeFeatureLayer_management(fcConfinementMargin_Segments,
                                          lyrConfinementEdgeSegments)
        arcpy.MakeFeatureLayer_management(fcChannelMargin_Segments,
                                          lyrChannelEdgeSegments)

        ## Prepare Filtered Margins
        fcFilterSplitPoints = gis_tools.newGISDataset(scratchWorkspace,
                                                      "FilterSplitPoints")
        arcpy.FeatureVerticesToPoints_management(fcConfinementMargin_Segments,
                                                 fcFilterSplitPoints,
                                                 "BOTH_ENDS")

        # Transfer Confining Margins to Stream Network ##
        arcpy.AddMessage("Transferring Confining Margins to Stream Network...")
        fcConfinementMarginSegmentsBankSide = gis_tools.newGISDataset(
            scratchWorkspace, "ConfinementMarginSegmentsBank")
        lyrConfinementMarginSegmentsBankside = gis_tools.newGISDataset(
            "Layer", "lyrConfinementMarginSegmentsBankside")

        field_map = """BankSide "BankSide" true true false 255 Text 0 0 ,First,#,""" + fcChannelBankPolygons + """,BankSide,-1,-1"""
        arcpy.SpatialJoin_analysis(fcConfinementMargin_Segments,
                                   fcChannelBankPolygons,
                                   fcConfinementMarginSegmentsBankSide,
                                   "JOIN_ONE_TO_ONE", "KEEP_ALL", field_map)

        arcpy.MakeFeatureLayer_management(
            fcConfinementMarginSegmentsBankSide,
            lyrConfinementMarginSegmentsBankside)
        arcpy.SelectLayerByAttribute_management(
            lyrConfinementMarginSegmentsBankside, "NEW_SELECTION",
            """ "BankSide" = 'LEFT'""")

        fcStreamNetworkConfinementLeft = transfer_line(
            lyrConfinementMarginSegmentsBankside, fcStreamNetworkDissolved,
            "LEFT")
        arcpy.SelectLayerByAttribute_management(
            lyrConfinementMarginSegmentsBankside, "NEW_SELECTION",
            """ "BankSide" = 'RIGHT'""")
        fcStreamNetworkConfinementRight = transfer_line(
            lyrConfinementMarginSegmentsBankside, fcStreamNetworkDissolved,
            "RIGHT")

        # This intersection step combines the two outputs from transfer_line() into a single dataset using intersection
        arcpy.AddMessage("... Constructing segmented stream network")
        fcConfinementStreamNetworkIntersected = gis_tools.newGISDataset(
            scratchWorkspace, "ConfinementStreamNetworkIntersected")
        arcpy.Intersect_analysis(
            [fcStreamNetworkConfinementLeft, fcStreamNetworkConfinementRight],
            fcConfinementStreamNetworkIntersected, "NO_FID")  # TODO no fid?

        #Re-split centerline by segments
        arcpy.AddMessage("Determining Confinement State on Stream Network...")
        fcRawConfiningNetworkSplit = gis_tools.newGISDataset(
            scratchWorkspace, "RawConfiningNetworkSplit")
        arcpy.SplitLineAtPoint_management(
            fcConfinementStreamNetworkIntersected, fcNetworkSegmentPoints,
            fcRawConfiningNetworkSplit, "0.01 Meters")

        #Table and Attributes
        arcpy.AddMessage("... Adding fields and attributing")
        arcpy.AddField_management(fcRawConfiningNetworkSplit,
                                  "Con_Type",
                                  "TEXT",
                                  field_length="6")
        arcpy.AddField_management(fcRawConfiningNetworkSplit, "IsConfined",
                                  "SHORT")
        gis_tools.resetField(fcRawConfiningNetworkSplit, "IsConstric", "SHORT")

        lyrRawConfiningNetwork = gis_tools.newGISDataset(
            "Layer", "lyrStreamNetworkCenterline1")
        arcpy.MakeFeatureLayer_management(fcRawConfiningNetworkSplit,
                                          lyrRawConfiningNetwork)

        arcpy.SelectLayerByAttribute_management(lyrRawConfiningNetwork,
                                                "NEW_SELECTION",
                                                """ "Con_LEFT" = 1""")
        arcpy.CalculateField_management(lyrRawConfiningNetwork, "Con_Type",
                                        "'LEFT'", "PYTHON")

        arcpy.SelectLayerByAttribute_management(lyrRawConfiningNetwork,
                                                "NEW_SELECTION",
                                                """ "Con_RIGHT" = 1""")
        arcpy.CalculateField_management(lyrRawConfiningNetwork, "Con_Type",
                                        "'RIGHT'", "PYTHON")

        arcpy.SelectLayerByAttribute_management(
            lyrRawConfiningNetwork, "NEW_SELECTION",
            """ "Con_LEFT" = 1 AND "Con_RIGHT" = 1""")
        arcpy.CalculateField_management(lyrRawConfiningNetwork, "Con_Type",
                                        "'BOTH'", "PYTHON")
        arcpy.CalculateField_management(lyrRawConfiningNetwork, "IsConstric",
                                        "1", "PYTHON")

        arcpy.SelectLayerByAttribute_management(lyrRawConfiningNetwork,
                                                "SWITCH_SELECTION")
        arcpy.CalculateField_management(lyrRawConfiningNetwork, "IsConstric",
                                        "0", "PYTHON")

        arcpy.SelectLayerByAttribute_management(
            lyrRawConfiningNetwork, "NEW_SELECTION",
            """ "Con_LEFT" = 1 OR "Con_RIGHT" = 1""")
        arcpy.CalculateField_management(lyrRawConfiningNetwork, "IsConfined",
                                        "1", "PYTHON")

        arcpy.SelectLayerByAttribute_management(lyrRawConfiningNetwork,
                                                "SWITCH_SELECTION")
        arcpy.CalculateField_management(lyrRawConfiningNetwork, "IsConfined",
                                        "0", "PYTHON")
        arcpy.CalculateField_management(lyrRawConfiningNetwork, "Con_Type",
                                        "'NONE'", "PYTHON")

        # Integrated Width
        # This code is never executed as the Boolean is ALWAYS FALSE!
        fcIntersectLineNetwork = fcInputStreamLineNetwork
        if boolIntegratedWidthAttributes:
            fcIntegratedChannelWidth = gis_tools.newGISDataset(
                scratchWorkspace, "IW_Channel")
            fieldIWChannel = integrated_width(fcInputStreamLineNetwork,
                                              fcChannelSegmentPolygons,
                                              fcIntegratedChannelWidth,
                                              "Channel", False)

            fcIntegratedWidth = gis_tools.newGISDataset(
                scratchWorkspace, "IW_ChannelAndValley")
            fieldIWValley = integrated_width(fcIntegratedChannelWidth,
                                             fcInputValleyBottomPolygon,
                                             fcIntegratedWidth, "Valley", True)

            fieldIWRatio = gis_tools.resetField(fcIntegratedWidth, "IW_Ratio",
                                                "DOUBLE")
            exp = "!" + fieldIWValley + r"! / !" + fieldIWChannel + "!"
            arcpy.CalculateField_management(fcIntegratedWidth, fieldIWRatio,
                                            exp, "PYTHON_9.3")
            fcIntersectLineNetwork = fcIntegratedWidth

        # Final Output
        arcpy.AddMessage("Preparing Final Output...")
        if arcpy.Exists(fcOutputRawConfiningState):
            arcpy.Delete_management(fcOutputRawConfiningState)
        arcpy.Intersect_analysis(
            [fcRawConfiningNetworkSplit, fcIntersectLineNetwork],
            fcOutputRawConfiningState, "NO_FID")

        # Call function to clean up fields and add additional attribution to confinement margins layer
        arcpy.AddMessage("Cleaning up confinement margins layer...")
        bOK = prepConfinementOutput(fcConfiningMargins,
                                    fcConfinementMarginSegmentsBankSide)
        if not bOK:
            arcpy.AddWarning(
                "An error occurred whilst preparing Confinement Margins layer!"
            )
            arcpy.AddWarning(
                "Make sure it has a valid MarginID and Length field")
        return True
    except arcpy.ExecuteError:
        # Geoprocessor threw an error
        arcpy.AddError(arcpy.GetMessages(2))
        return False
    except Exception as e:
        arcpy.AddError("Error in ConfiningMargins main function: " + str(e))
        return False