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