I am a fisheries student and am currently tracking fish movement in a lake. I am trying to assess their optimum/minimized distance moved between each sequential location for each fish. However, I can only figure out how to get straight line distance. Straight line distance does not take into account that I am tracking fish that cannot swim over islands, points, land, etc. I have a shapefile of the lake and am trying to determine the minimized distance between each sequential location while telling ArcGIS Pro to not let the route go OUTSIDE OF THE POLYGON. Does anyone have any experience doing this?

  • This is a simple Euclidean cost surface. Mask out the land as nodata.
    – Vince
    Sep 14 at 1:54

1 Answer 1


One approach is using Cost Distance tool from Spatial Analyst, i.e. raster based technique, which will produce something like this, depending on raster resolution: enter image description here

For every pair of points you'll need to re-calculate Cost Distance and Backlink rasters.

More elegant (and way much faster), in my opinion, is Network Analyst solution:

enter image description here

You are right, network analyst tutorials are focused on streets. I'd use NA extension for high level navigation system, market research or evacuation plans, so I can take into account thigs like 'one way', 'speed limit', etc. This might mean paying for ready datasets. Fish doesn't care about stuff like 'left turn only'...

I think this is what you need:

  1. Simple network and efficient way to build it
  2. Combine points sequence into pairs (script)
  3. Find shortest paths between pairs (script).

I'd use workflow as follows. Place many points inside lake, incl. islands. Triangulate them and fish points into TIN and use convex hulls of the island to erase parts of the TIN. Extract TIN edges and nodes: enter image description here

/I used centers of small hexagon to generate points, but many Ks of random points will suffice. This will result in a twisty paths for foraging fish during her travel.../

Nodes and edges are geometries of your network. The only thing that is missing is info on end points/nodes in edges table..

enter image description here

Your network is ready!

Use networkx module in Python script:

import networkx as nx
# find network items in a map
mxd = arcpy.mapping.MapDocument("CURRENT")
EDGES,NODES = [arcpy.mapping.ListLayers(mxd,item)[0] for item in 'EDGES','NODES']
## create undirected graph
G = nx.Graph()
with arcpy.da.SearchCursor(EDGES,("OID@","FI","TI","LENGTH")) as cursor:
    for fid, f,t,w in cursor:
## get selected nodes (sort them by seq.number - not shown here!) and pair them
selectedNodes = NODES.getSelectionSet()
from_to_nodes = zip(selectedNodes[:-1],selectedNodes[1:])
## connect nodes in pair
links2select = []
for F,T in from_to_nodes:
    path = nx.dijkstra_path(G, F, T)
    for f,t in zip(path[:-1],path[1:]):
## select relevant edges
EDGES.setSelectionSet ("NEW",links2select)

To compute single fish path: enter image description here

No matter the tool you'll pick, coding skills are must have. Note: script above is using very old version of networkx and works in Arcmap. It will not work in PRO, because they've changed many things in arcpy and there are changes in networkx latest version that comes with PRO.

  • Do you have any good resources on the basics on how to use the Network Analyst tool? Having trouble figuring out how to get the necessary inputs to make the extension work properly. Sep 14 at 14:53
  • For example, every example I see online uses streets of some sort as the input network dataset, but I need to create my own network dataset for the lake and am unsure on how to do this. Sep 14 at 15:07
  • Awesome Felix, this is awesome information. I will have to give this a try. Sep 18 at 18:52

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.