# Minimized distance between points while staying INSIDE of a designated polygon

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. Sep 14 at 1:54

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:

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:

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:

/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..

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:
G[f][t]['fid']=fid
## 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
for F,T in from_to_nodes:
path = nx.dijkstra_path(G, F, T)
for f,t in zip(path[:-1],path[1:]):