1

I'm trying to calculate total stream length for multiple, overlapping watersheds (i.e., each watershed contains the watersheds upstream of it). I have a flowline layer that I've run through the Intersect tool so that they end on the boundaries of the watersheds (not the overlapping watersheds because that created multiples of the same flowlines). My idea was to create a cursor that would iterate through the watershed table, select the individual watershed, then use the select-by-location tool to select the only the stream segments within the selected watershed. However, every time I try this, I get the error: "Error in executing tool." Here's the code so far:

watershed = "Sampled_Watersheds"
flowline = "Flowline_Intersect2"

with arcpy.da.SearchCursor(watershed, "Stream_Length") as cursor:
  for row in cursor:
    arcpy.SelectLayerByAttribute_management(watershed, "NEW_SELECTION", [row])
    arcpy.SelectLayerByLocation_management(flowline, "COMPLETELY_WITHIN", watershed, "NEW_SELECTION")

After, I get the selection, I want to add the total stream length to the watershed table. Would something like the follow work?

arcpy.CalculateField_management(watershed, "Stream_Length", "SUM(!Flowline_Streams.Length_km!)","PYTHON")
8
  • It sounds like you probably want to redesign the data structure. Overlapping watersheds doesn't make much sense. Nested watersheds makes sense--is that what you meant? Do you have nested watersheds but distinct features at each level, rather than just having the lowest-level watersheds attributed with their respective higher-level watersheds? You'd be surprised how often implementing a normalized data structure will simplify analysis problems. Let me know if you need help cleaning it up.
    – Tom
    Nov 9, 2015 at 21:49
  • @Tom - I have multiple sampling points within the same stream system. I used the sampling points as pour points in the archydro tool. After I had those individual watersheds, I selected all watersheds upstream of a sampling point, created a layer from selection, then dissolved all of the little watersheds into one watershed. After doing this for all of the sample points, I merged all of the newly created watersheds into a single shapefile. Because of this, the watersheds physically overlap each other within the layer. Is that what you mean by nested?
    – TMoore
    Nov 10, 2015 at 17:52
  • Intersect them, output polyline. Summarise using catchment id
    – FelixIP
    Nov 10, 2015 at 18:10
  • @TMoore, okay, I had thought you were using NHDPlus or something similar and maybe were conflating catchments and watersheds. So, then my next question is: are you trying to calculate total stream length for each watershed or for all watersheds?
    – Tom
    Nov 10, 2015 at 18:26
  • @FelixIP Not the clearest instructions, but I figured out what you were saying, and it worked! Thank you! I know it worked because I had already gone through and done the calculations manually. I made this post because I was looking for a quicker way to do it in the future (I had 108 sampling points).
    – TMoore
    Nov 10, 2015 at 18:34

1 Answer 1

2

Scripting this task is wrong way to go as I mentioned in my comment, but if OP insists, the code below should work on FGDB inputs and it doesn't matter if streams are not split at polygons boundaries or not

import arcpy
from arcpy import env
env.overwriteoutput=True
clipped="in_memory\clipped"
g = arcpy.Geometry()

mxd = arcpy.mapping.MapDocument("CURRENT")
watershed = arcpy.mapping.ListLayers(mxd,"Sampled_Watersheds")[0]
flowline = arcpy.mapping.ListLayers(mxd,"Flowline_Intersect2")[0]

m=0
with arcpy.da.UpdateCursor(watershed, ("Shape@","Stream_Length")) as cursor:
  for row in cursor:
      arcpy.Clip_analysis (flowline, row[0], clipped)
      geometryList=arcpy.CopyFeatures_management(clipped,g)
      lengths=[feat.length for feat in geometryList]
      row[1]=sum(lengths)
      cursor.updateRow(row)
      m+=1
      arcpy.AddMessage('%i m of streams found in catchment %i' %(row[1],m))
arcpy.Delete_management("in_memory")

Note: select layer by location is very low performace action, I use it when/if there is no alternative

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.