Download the runnable example here

Step 1: Calculate the un-directional minimum distances

Definition: the un-directional minimum distance between any two reference sites is the minimum distance consists of a number of links connecting these two reference sites, regardless of their directions.
Notation: umdrsi-rsj - un-directional minimum distance between reference site rsi and reference site rsj
Method: Dijkstra minimum distance algorithm.

Step 2: Determine a given reference site's relative position

Given a link of interests [F-T], the table below shows all possible positions that a random reference site rsi can be relative to link [F-T]:

Relative Position Explanation Conditions
Upstream --(rsi)-------------------------
----------(F)=====>(T)----------
umdrsi-F < umdrsi-T AND length(F-T) < umdrsi-T
Overlap F ----------(F/rsi)---------------
----------(F/rsi)===>(T)--------
umdrsi-F = 0
In Between --------------(rsi)-------------
----------(F)=====>(T)----------
umdrsi-F + umdrsi-T <= length(F-T)
Overlap T -----------------(T/rsi)--------
----------(F)===>(T/rsi)--------
umdrsi-T = 0
Downstream ------------------------(rsi)---
----------(F)=====>(T)----------
umdrsi-F > umdrsi-T AND length(F-T) < umdrsi-F

Step 3: Determine a given link's relative position

Given another link [Fi-Ti], its position can be of the following 25 cases relative to link [F-T]:

Fi's relative position to link [F-T]
Upstream Overlap F In Between Overlap T Downstream
Ti's
relative
position
to
link
[F-T]
Upstream Case1 Case2 Case3 Case4 Case5
Overlap F Case6 Case7 Case8 Case9 Case10
In Between Case11 Case12 Case13 Case14 Case15
Overlap T Case16 Case17 Case18 Case19 Case20
Downstream Case21 Case22 Case23 Case24 Case25

Step 4: Determine the direction and the distance between two crashes

When calculating the distance from a current primary crash crashcur (occurred on link [F-T]) to a potential secondary crash crashi (occurred on link [Fi-Ti]), the following equation is used:
d = sign1*(sign2*umdFi-F - offsetcrashcur) + offsetcrashi.
where,
umdFi-F, offsetcrashi, and offsetcrashcur are all non-negative distances. When d > 0, crashi is downstream of crashcur in either direction; when d < 0, crashi is upstream of crashcur in either direction. When link [Fi-Ti], is in the same direction to link [F-T], sign1 = 1, otherwise sign1 = -1. When Fi is upstream of link [F-T], sign2 = -1; when Fi overlaps with F, sign2 = 0; otherwise, sign2 = 1. Below is a summary matrix:

Fi's relative position to link [F-T]
Upstream Overlap F In Between Overlap T Downstream
Ti's
relative
position
to
link
[F-T]
Upstream Case1
if umdFi-F > umdTi-F, sign1 = 1,
if umdFi-F < umdTi-F, sign1 = -1;
sign2 = -1
Case2
sign1 = -1;
sign2 = 0;
Case3
sign1 = -1;
sign2 = 1;
Case4
sign1 = -1;
sign2 = 1;
Case5
sign1 = -1;
sign2 = 1;
Overlap F Case6
sign1 = 1;
sign2 = -1;
Case7
not exist
Case8
sign1 = -1;
sign2 = 1;
Case9
sign1 = -1;
sign2 = 1;
Case10
sign1 = -1;
sign2 = 1;
In Between Case11
sign1 = 1;
sign2 = -1;
Case12
sign1 = 1;
sign2 = 0;
Case13
if umdFi-F < umdTi-F, sign1 = 1,
if umdFi-F > umdTi-F, sign1 = -1;
sign2 = 1
Case14
sign1 = -1;
sign2 = 1;
Case15
sign1 = -1;
sign2 = 1;
Overlap T Case16
sign1 = 1;
sign2 = -1;
Case17
sign1 = 1;
sign2 = 0;
Case18
sign1 = 1;
sign2 = 1;
Case19
not exist
Case20
sign1 = -1;
sign2 = 1;
Downstream Case21
sign1 = 1;
sign2 = -1;
Case22
sign1 = 1;
sign2 = 0;
Case23
sign1 = 1;
sign2 = 1;
Case24
sign1 = 1;
sign2 = 1;
Case25
if umdFi-F < umdTi-F, sign1 = 1,
if umdFi-F > umdTi-F, sign1 = -1;
sign2 = 1

Appendix A: Enumeration of All Cases

Case1(table)

Case2(table)

Case3(table)

Case4(table)

Case5(table)

Case6(table)

Case7(table)

Such case doen't exist since Fi and Ti overlap.

Case8(table)

Case9(table)

Case10(table)

Case11(table)

Case12(table)

Case13(table)

Case14(table)

Case15(table)

Case16(table)

Case17(table)

Case18(table)

Case19(table)

Such case doen't exist since Fi and Ti overlap.

Case20(table)

Case21(table)

Case22(table)

Case23(table)

Case24(table)

Case25(table)

<