Natural Pi #2 - River
MATL, 48 44 42 37 33 bytes

Quite a few bytes saved thanks to rahnema1's idea (Octave answer) of collapsing two convolutions into one

t5BQ4B&amp;vX^Z+*ssGt3Y6Z+1=*&amp;fdwdYy/


This takes the input as a binary matrix, with ; as row separator. 1 corresponds to hash and 0 to space.

Try it online! Or verify all test cases.

Here's a format converter that takes inputs as 2D char arrays (again, with ; as separator) and produces string representations of the corresponding binary matrices.

Explanation

This was fun! The code uses three two 2D-convolutions, each for a different purpose:


To detect vertical and horizontal neighbours, which contribute a distance of 1, the required mask would be

0 1 0
1 0 1
0 1 0


But we only want each pair of neighbours to be detected once. So we take half the mask (and the last row of zeros can be removed):

0 1 0
1 0 0


Similarly, to detect diagonal neighbours, which contribute a distance of sqrt(2), the mask would be

1 0 1
0 0 0
1 0 1


but by the same reasoning as above it becomes

1 0 1
0 0 0


If this mask is multiplied by sqrt(2) and added to the first, the two convolutions can be replaced by one convolution with the combined mask

sqrt(2) 1  sqrt(2)
1       0        0

Start and end points are, by definition, the points with only one neighbour. To detect them we convolve with 

1 1 1
1 0 1
1 1 1


and see which points give 1 as result.


To produce the combined mask of item 1 it's shorter to generate its square and then take the square root. The mask in item 2 is a predefined literal.

t     % Take input matrix implicitly. Duplicate
5B    % 5 in binary: [1 0 1]
Q     % Add 1; [2 1 2]
4B    % 4 in binary: [1 0 0]
&amp;v    % Concatenate vertically
X^    % Square root of each entry
Z+    % 2D convolution, maintaining size
*     % Multiply, to only keep results corresponding to 1 in the input
ss    % Sum of all matrix entries. This gives total distance
Gt    % Push input again. Duplicate
3Y6   % Predefined literal. This gives third mask
Z+    % 2D convolution, maintaining size
1=    % Values different than 1 are set to 0
*     % Multiply, to only keep results corresponding to 1 in the input
&amp;f    % Push array of row indices and array of column indices of nonzeros
d     % Difference. This is the horizontal difference between start and end
wd    % Swap, difference. This is the vertical difference between start and end 
Yy    % Hypothenuse. This gives total distance in straight line
/     % Divide. Display implicitly