Skip to content

Commit 08e306a

Browse files
committed
feat: add detailed data flow documentation for DirectionFilterHelper
1 parent 9240113 commit 08e306a

1 file changed

Lines changed: 108 additions & 0 deletions

File tree

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# DirectionFilterHelper Data Flow
2+
3+
```mermaid
4+
flowchart TD
5+
Start([filterPathsByDirection]) --> CheckNull{lineStrings null<br/>or empty<br/>or size == 1?}
6+
CheckNull -->|Yes| ReturnInput[Return lineStrings<br/>or empty list]
7+
CheckNull -->|No| CheckDirection{direction ==<br/>BOTH or UNKNOWN?}
8+
9+
CheckDirection -->|Yes| ReturnAll[Return all lineStrings]
10+
CheckDirection -->|No| GetPoints[Get terminal points:<br/>- furthestPointOfFirstPath<br/>- furthestPointOfSecondPath]
11+
12+
GetPoints --> CalcSeparation[Calculate total separation<br/>and half separation<br/>using Pythagorean theorem]
13+
14+
CalcSeparation --> InitSelect[Initialize:<br/>selectFirstPath = true<br/>isNonCardinal = check direction]
15+
16+
InitSelect --> SwitchDirection{Switch on<br/>direction type}
17+
18+
SwitchDirection -->|NORTH or SOUTH| CheckYDiff{Y difference <<br/>half separation?}
19+
CheckYDiff -->|Yes| CheckNonCardinal
20+
CheckYDiff -->|No| CompareY[compareCoordinates on Y<br/>Update selectFirstPath]
21+
CompareY --> CheckNonCardinal
22+
23+
SwitchDirection -->|EAST or WEST| CheckXDiff{X difference <<br/>half separation?}
24+
CheckXDiff -->|Yes| CheckNonCardinal
25+
CheckXDiff -->|No| CompareX[compareCoordinates on X<br/>Update selectFirstPath]
26+
CompareX --> CheckNonCardinal
27+
28+
SwitchDirection -->|Other| CheckNonCardinal{Is non-cardinal<br/>direction?}
29+
30+
CheckNonCardinal -->|No| ReturnSelected
31+
CheckNonCardinal -->|Yes| CalcBearing[Calculate bearing<br/>using AngleCalc.calcAzimuth]
32+
33+
CalcBearing --> DetermineTarget[Determine target bearing<br/>based on direction<br/>and buildUpstream]
34+
35+
DetermineTarget --> CalcDiff[Calculate angular difference<br/>normalize to 0-180°]
36+
37+
CalcDiff --> CheckBearing{Difference > 120°?}
38+
CheckBearing -->|Yes| SetFalse[selectFirstPath = false]
39+
CheckBearing -->|No| KeepTrue[selectFirstPath stays true]
40+
41+
SetFalse --> ReturnSelected[Return selected path<br/>based on selectFirstPath]
42+
KeepTrue --> ReturnSelected
43+
44+
ReturnSelected --> End([End])
45+
ReturnInput --> End
46+
ReturnAll --> End
47+
48+
style Start fill:#e1f5ff
49+
style End fill:#e1f5ff
50+
style ReturnSelected fill:#c8e6c9
51+
style ReturnInput fill:#c8e6c9
52+
style ReturnAll fill:#c8e6c9
53+
style CheckNull fill:#fff9c4
54+
style CheckDirection fill:#fff9c4
55+
style CheckNonCardinal fill:#fff9c4
56+
style CheckYDiff fill:#fff9c4
57+
style CheckXDiff fill:#fff9c4
58+
style CheckBearing fill:#fff9c4
59+
style SwitchDirection fill:#ffe0b2
60+
```
61+
62+
## Flow Description
63+
64+
The diagram illustrates the data flow through the `DirectionFilterHelper.filterPathsByDirection()` method:
65+
66+
1. **Entry point**: `filterPathsByDirection` method receives lineStrings, buildUpstream flag, and direction
67+
2. **Early exits**: Returns immediately for null/empty lists or BOTH/UNKNOWN directions
68+
3. **Cardinal direction handling**: Uses coordinate comparison for N/S/E/W with separation checks
69+
4. **Non-cardinal direction handling**: Uses bearing calculations for NE/SE/SW/NW
70+
5. **Decision logic**: The `selectFirstPath` boolean determines which path is returned
71+
6. **Helper methods**: `getTerminalPoint` and `compareCoordinates` are invoked within the flow
72+
73+
## Pythagorean Theorem in Distance Calculation
74+
75+
The algorithm uses the Pythagorean theorem to calculate the total separation between the terminal points of two paths:
76+
77+
```
78+
Point 2 (x₂, y₂)
79+
80+
/|
81+
/ |
82+
/ |
83+
totalSep / | yDiff = |y₂ - y₁|
84+
/ |
85+
/ |
86+
/ |
87+
/ |
88+
/ |
89+
●---------+
90+
Point 1 (x₁, y₁)
91+
92+
xDiff = |x₂ - x₁|
93+
94+
95+
totalSeparation = √(xDiff² + yDiff²)
96+
halfSeparation = totalSeparation / 2
97+
```
98+
99+
**Key Concepts:**
100+
- **Point 1**: Terminal point of first LineString (`furthestPointOfFirstPath`)
101+
- **Point 2**: Terminal point of last LineString (`furthestPointOfSecondPath`)
102+
- **xDiff**: Horizontal distance between points = `|x₂ - x₁|`
103+
- **yDiff**: Vertical distance between points = `|y₂ - y₁|`
104+
- **totalSeparation**: Euclidean distance using `√((x₂ - x₁)² + (y₂ - y₁)²)`
105+
- **halfSeparation**: Used as threshold to determine if paths are divergent enough for directional filtering
106+
107+
**Example Use Case:**
108+
For NORTH/SOUTH filtering, if `yDiff < halfSeparation`, the paths are too horizontal (not divergent enough in the Y direction) to make a reliable directional determination, so the algorithm defaults to returning the first path.

0 commit comments

Comments
 (0)