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?
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:
- Simple network and efficient way to build it
- Combine points sequence into pairs (script)
- 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..
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) 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.add_edge(f,t,weight=w) 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 links2select =  for F,T in from_to_nodes: path = nx.dijkstra_path(G, F, T) for f,t in zip(path[:-1],path[1:]): links2select.append(G[f][t]['fid']) ## select relevant edges EDGES.setSelectionSet ("NEW",links2select)
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.