コード例 #1
0
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
コード例 #2
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
コード例 #3
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
コード例 #4
0
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
コード例 #5
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