# Create tracks from GPS points honoring polygon barriers

I have fish tracking data from a river. The data include positions, times and tag ids. Time interval between positions may be several days. I would like to create a polyline track for each fish tag that stays within a polygon that defines the shoreline of the river. I am looking for a procedure or extension or add-in to use in ArcGIS or one of several open source GIS.

• I hesitate to suggest this because it could be extremely time consuming, but theoretically you could use your river feature class as a cost surface and calculate the least cost path between each location and the next location. This would force the lines to stay within the river banks. – phloem Feb 16 '15 at 23:03
• @phloem I've just done this using R - the time consumption will be dependent on the resolution of the rasterized river map and the number of points to be interpolated. But my example below runs pretty quickly on my 6 year old laptop. – Spacedman Mar 17 '16 at 9:38

Here's a solution using the `gdistance` package in R for computing shortest paths according to a cost surface derived from a raster:

First read in the raster of the river map. In my case this has values of 0 for the rivers and 255 for dry land:

``````> require(raster); require(gdistance)
> rivers = raster("./surface.tif")
``````

Next convert to categorical data, with a cutoff anywhere between 0 and 255 - this defines which values are river and which land:

``````> rfac = asFactor(rivers<100)
``````

Now compute the transition matrix based on this categorical raster, using the values to define areas where paths can go, and an 8-direction transition. Bump this to 16 if you want finer detailed paths (but takes longer to compute):

``````> rfactr = transition(rfac, "areas", 8)
``````

Now I have a little matrix with the first row the start and second row the destination:

``````> pts
[,1]     [,2]
[1,] -10268153 16602667
[2,]  -9064803 15332707
``````

Now compute the shortest path and return a lines object (can also return a raster cell coverage raster):

``````> path = shortestPath(rfactr[[1]], pts[1,], pts[2,],"SpatialLines")
``````

And lets see the magic:

``````> plot(rivers)
> lines(path,col=2,lwd=2)
> points(pts)
``````

You only need compute the transition matrix once, computing more paths is just a call to `shortestPath`, which took about a second on my very old laptop. It'll depend on the resolution of your raster, in my case this is 555x783 pixels. A modern machine could do this in the blink of an eye. Must upgrade...

If you've not used R before then be assured its pretty capable as a GIS with a programming language attached...

Both ArcGIS and QGIS would do the trick (assume you have got a csv spreadsheet in hand):

ArcGIS version: