[GIS] How to find the watershed for each outlet point and sum values within it

arcgis-desktopNetworkspatial statisticswatershed

I have the following files to work with:

  1. Stream network of a basin;
  2. Outlet points for each segment* of the network and
  3. Points which represent water withdrawals along of the stream, which are not located in the stream, but near of segments.

*segment = a line with a start point and an outlet point.

My goal is to calculate the sum of withdrawals located upstream of each outlet points.

My first attempt was using model builder, iterating over each outlet point. For each of them, I delineated the watershed and calculated the sum using Zonal Statistics (summing withdrawals contained by the watershed). But it didn't work well because ArcGIS aren't calculating watershed properly. I do not know why…

I'm wondering if I can figure out how to select directly upstream watersheds each iteration, assuming I've already obtained a feature containing the watersheds for each segment.

NOTICE: I don't want to find the watershed for each segment. I want to find the watershed for each outlet point. That's more comprehensive.

Best Answer

Assuming that each withdrawal point is related to the closest stream segment, we can do the following:

  1. Use the split line at point tool to split the stream line into segments based on outlet points (depending on your data you may already have this). Make sure that each point has an ID, which should relate to stream order (see one method below for an example in Python).
  2. Use the generate near table tool to generate a table that will link your withdrawal points to the nearest stream segment. Check the only get closest checkbox so you only get one result for each point.
  3. Join the withdrawal amout to the near table to associate with the segment IDs.
  4. Use the summary statistics tool to sum the withdrawal amount grouped by segment ID.
  5. Join the output withdrawal sums to your stream segment, select those segments upstream from the point of interest, and sum the total withdrawals (again, see below for one way to do this).

And example of IDing the segments using Python.

import arcpy

#Written assuming arcGIS 10
#Note this will require modification to run...

start_pts = {}
end_pts = {}

for segment in arcpy.SearchCursor("segmented_line"):
    start_pts[segment.SEGMENT_ID] = segment.SHAPE.getObject(0) #SHAPE returns an arcpy.Array
                                                               #object containing points for
                                                               #geom type line
    end_pts[segment.SEGMENT_ID] = segment.SHAPE.getObject(segment.SHAPE.count)

try:
    #cleanup as you can only have one cursor open at once, otherwise wackiness
    del segment
except:
    pass

rows = arcpy.InsertCursor("start_pts")
for start in start_pts:
    row = rows.newRow()
    row.SHAPE = start_pts[start]
    row.SEGMENT_ID = start
    rows.insertRow(row)

try:
    #more cleanup
    del row
    del rows
except:
    pass

arcpy.SpatialJoin_analysis(start_pts, outlet_pts, "start_outlet_pts",
                           "JOIN_ONE_TO_ONE", match_option="WITHIN_A_DISTANCE",
                           search_radius="some metres")

arcpy.JoinField_management("segmented_line", "SEGMENT_ID", "start_outlet_pts", "SEGMENT_ID", "OUTLET_ID")

################################################################################
##Repeat for end_pts
################################################################################

Once I get a bit of time later I'll come back and update this answer with a bit of script to build a network using networkx to help sum the values...

Hope this helps!