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.

  • 2
    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)

shortest path analysis

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:

  1. Use 'Add data' to add load your csv file onto ArcMAP;
  2. Right click the csv table choose 'Display XY', and set the right position field.
  3. Right click the new .event layer, export it to a shapefile (now you will have a point layer you can work with).
  4. if you have the polygon in hand already, you can then use 'Clip (Analysis)' tool to get all fish tags within that polygon (choose your polygon as then clip feature).
  5. lastly use'Points To Line (Data Management)'to create a line track.

QGIS version:

Simlar to ArcGIS: whereas in QGIS you will use 'Create a Layer from Delimited Text File' tool to load csv data, and Clip under 'Vector -> geoprocessing toolset'. I suggest you check out this plugin here: http://spatialgalaxy.net/2011/12/30/qgis-plugin-of-the-week-points-to-paths/

  • 2
    I think they were looking for a way to constrain the line within the river banks, which this will not do. – phloem Feb 16 '15 at 23:02
  • 1
    Phloem is right. all our fish locations are within the river, but connecting points to create a track generates tracks that cross land where the river goes around a bend or a peninsula sticks out into the river. I am looking for a way to keep the track in the river. – johnladd Feb 17 '15 at 16:31

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.