# Computing distance between two points "as the fish swims" [closed]

We have a layer named Hydrography which is the water area for a given assignment. I have a station point and a target point. I need to compute the distance between those two points but inside of the hydrography. (boats cannot go over land)

The DefenseService distance computation looks passable but it seems to be in a straight line since it does not take any Raster as input. The Euclidean seems to almost be there but I cannot find anything that is straight forward.

I am using ArcGIS Explorer 2500, ArcGIS for Server 10.1 SP1 Enterprise, and we are writing our services and tools in C#.

I have the loading of the hydrography, the creation of the IPoints, but at a loss as to what to do next!

Use the Cost Distance and Cost Path Tools from the Spatial Analyst Extension.

You can create a Raster from your Hydrography Polygons. Then assure that the raster cells that represent water get a low value (e.g. 1) and the other raster cells get a high value (e.g. 1000). You can then use this raster as cost distance raster in the Cost Path Tool.

I have done something similar for centrelines over canals and natural watercourses. The approach that I used was to TIN the points, bisect the TIN then create a second TIN from the original vertices and the bisectors then traverse using a modified Dijkstra's algorithm discarding options as soon as it is evident that they will not form the most simple solution. The modification was that the line could terminate at the 'solution' point or a previous path should one already exist. There is no out-of-the-box solution for this and if you're not a programmer or at least in a position to get on the good side of one your only option is to trace with an offset into a geodatabase and look at the shape_length field.

TIN = Triangular Irregular Network, a lattice of points and connecting lines such that each point is connected to its closest neighbors and no lines intersect. For this see http://en.wikipedia.org/wiki/Delaunay_triangulation. I didn't use the ESRI TIN objects, instead I found some code for triangulation and kept them in memory, something like http://www.codeproject.com/Articles/492435/Delaunay-Triangulation-For-Fast-Mesh-Generation.

For the shortest path algorithm see http://en.wikipedia.org/wiki/Dijkstra's_algorithm it has a nice picture; despite the complicated name it is really quite simple.

From the points forming the lines I did a Delaunay triangulation then found the mid point of each edge of the triangle (basic geometry... average X, average Y) and then inserted the points that fell within the polygons into the mesh which gives a centre path and links to all vertices on the boundary. Then excluding facets that follow the banks of the watercourse trace the network using Dijkstra's algorithm and you will eventually find a path from point A to point B running approximately down the centre of the watercourses. There will be a lot of possible paths so I kept a weight on each apex and stopped a path when the cumulative length exceeded the length already recorded, and if it was less then update the apex with the shorter cumulative length - this reduces the amount of paths that are traced, and there may be quite a lot; in the end I needed to multi thread the application to get reasonable response times.

Alternately, once triangulated, you could turn the triangles' edges into two point lines as a feature class, build a network and then do a trace. I'm sure that the ESRI tracing routines are much quicker than mine but I had a specific need and couldn't solve it using geometric networks.

Here is all that I've learned in digging into this issue and getting a complete distance between points call.

Our first issue stemmed from the static nature of RasterCatalog. Changing the rasters that this is based on does NOT change the raster inside the RasterCatalog. It turned out that ours had an ancient version that was nowhere near a coastline map. Lesson Learned: Rebuild the RasterCatalog EVERY TIME you change the Rasters it is based on.

The Distance Raster with weights added becomes a rather cumbersome thing to work with. Look at the following scenario: Original value of raster is 1 total distance I want to look at is 117 km. Cell size is 1 meter. If the raster is now a weighted value of 48, then the total distance I want to look become 117 km * 48!!! So distance in the CostDistance method is not the cell distance but the weighted distance, apparently adding the value in each cell until the sum of each cell = the value passed for total distance. Even if the cell size itself is 1 meter!!!

The distance raster is all focused upon a point of origin. So when you call the CostDistance routine you do not want to include the point of origin in that list. if you do you will get one point with a distance of 0. (this even stumped ESRI support)

While many of the methods use the Envelope to restrict their process, the two most expensive ones, setting a value to the raster and extracting a raster without an area within a polygon, ignore all envelope settings and automagically always apply this to the entire raster. Unfortunately for us, we can only shorten this by creating massive overlapping segments and assigning a segment to a specific boxed area. But in doing so we have to be careful (which is hard) that a primary operation area does not exist in the wrong overlapped area. (in other words all of our overlaps have to be carefully chosen to not contain any primary points of interest!) The reason for this is we navigate the RasterCatalog choosing the correct raster based on where the Coast Guard station chosen exists. To further complicate our process, the overlap must allow us to navigate up to 120km away from our point of origin without running off the edge of the map and not overlapped with other primary points of interest. Sheesh.

The only other things I've learned is that it is easy to math to the raster but when you want to either 'poke a hole' in the raster (blockages) or set a donut with a value and the inside of the donut having a value of 1 (delays like a lock) you end up with a complex combination of tools and ArcObject calls. Which leads to the final lesson learned: ArcObjects cannot do everything. So I am occasionally forced to do things in the slow, cumbersome tools that were all written in python. I also learned that ESRI tool developers knew nothing about maintaining consistency. Sometimes they took a raster database at other times they needed a raster and occasionally they needed a featureset. And they don't return the data in the same format that they require as input! So if you need to use a second tool that wants the output of the last tool in a different format then you have to go through the hefty exercise of finding out how to do that.