I'm a PhD student tasked with analyzing a very large set of fisheries surveys conducted within discrete stream reaches. Unfortunately, the only information provided on location of each reach is (a) the XY coordinates of the downstream boundary, and (b) the reach length, in river km (i.e., as ,measured along the path of the stream/river).

I've already attached the downstream coordinates to the stream 'flowlines' feature class provided by the National Hydrography Dataset (NHDPlusV2, if relevant), but I'm really struggling with how to obtain XY coordinates for the upstream range boundary.

It did occur to me that I could create a buffer surrounding each downstream point, intersect it with the flowlines feature class, and pull the highest-elevation point of intersection -- but this would probably introduce considerable error where streams are more sinuous. As a newcomer to ArcGIS Pro, I've failed thus far to figure out how to 'extend' a point upstream along a flowline by a pre-specified distance. I don't even necessarily need to create a stream segment -- I just need to obtain the coordinates for the upstream range boundary in order to calculate elevational gradient, etc.

  • 1
    Welcome to GIS SE! As a new user be sure to take the Tour to learn about our focussed Q&A format. As it stands I think your question would benefit from being revised to try and make what you are asking clearer. I recommend reviewing meta.gis.stackexchange.com/a/3353/115 for tips on how to structure a good question.
    – PolyGeo
    Jun 8, 2021 at 21:39
  • 1
    Have a look at the Arcmap tool RivEX, it has a create reach tool.
    – Hornbydd
    Jun 9, 2021 at 0:32

1 Answer 1


Run near tool between points and streams, create copy of your points. Rename layer of streams to STREAMS in table of content of your map document. Run this field calculator expression on field Shape of the cloned points:

shpDict ={}
with arcpy.da.SearchCursor("STREAMS",("OID@","Shape@")) as cursor:
    for fid,shp in cursor: shpDict[fid] = shp

def moveIt(point,nearfid, dist2add):
   line = shpDict[nearfid]
   pointPos = line.measureOnLine(point) + dist2add
   return pNew


moveIt( !Shape!, !NEAR_FID!, -10)

enter image description here

It won't work if upstream junction is closer to point than recorded reach length or highly likely, your streams digitized in a wrong direction.

Note, I moved all points 10 m upstream, you can replace -10 by field name in point table that stores reach length.

This solution is improved version of one posted earlier.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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