riverjoin 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- riverjoin-0.1.0/PKG-INFO +47 -0
- riverjoin-0.1.0/README.md +31 -0
- riverjoin-0.1.0/pyproject.toml +32 -0
- riverjoin-0.1.0/setup.cfg +4 -0
- riverjoin-0.1.0/src/riverjoin/__init__.py +55 -0
- riverjoin-0.1.0/src/riverjoin/combined_workflow.py +218 -0
- riverjoin-0.1.0/src/riverjoin/modules/__init__.py +47 -0
- riverjoin-0.1.0/src/riverjoin/modules/attribute_transfer.py +614 -0
- riverjoin-0.1.0/src/riverjoin/modules/compare_linelength.py +149 -0
- riverjoin-0.1.0/src/riverjoin/modules/flowlines_buffer.py +149 -0
- riverjoin-0.1.0/src/riverjoin/modules/interactive_map.py +240 -0
- riverjoin-0.1.0/src/riverjoin/modules/perpendicularlines.py +1138 -0
- riverjoin-0.1.0/src/riverjoin/modules/project_initialization.py +61 -0
- riverjoin-0.1.0/src/riverjoin/modules/setup_hydrofabric.py +120 -0
- riverjoin-0.1.0/src/riverjoin/modules/situation_checker.py +67 -0
- riverjoin-0.1.0/src/riverjoin/modules/traced_downstream.py +295 -0
- riverjoin-0.1.0/src/riverjoin/utilis.py +77 -0
- riverjoin-0.1.0/src/riverjoin.egg-info/PKG-INFO +47 -0
- riverjoin-0.1.0/src/riverjoin.egg-info/SOURCES.txt +20 -0
- riverjoin-0.1.0/src/riverjoin.egg-info/dependency_links.txt +1 -0
- riverjoin-0.1.0/src/riverjoin.egg-info/requires.txt +8 -0
- riverjoin-0.1.0/src/riverjoin.egg-info/top_level.txt +1 -0
riverjoin-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: riverjoin
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: This is a river join implementation in Python.
|
|
5
|
+
Author-email: Supath Dhital <sdhital@crimson.ua.edu>, Yixian Chen <ychen223@ua.edu>
|
|
6
|
+
Project-URL: Homepage, https://github.com/sdmlua/riverjoin_py
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: geopandas
|
|
10
|
+
Requires-Dist: pathlib
|
|
11
|
+
Requires-Dist: fiona
|
|
12
|
+
Requires-Dist: folium
|
|
13
|
+
Provides-Extra: dev
|
|
14
|
+
Requires-Dist: pytest; extra == "dev"
|
|
15
|
+
Requires-Dist: black; extra == "dev"
|
|
16
|
+
|
|
17
|
+
# Framework for Spatially Joining two Hydrofabric Flowlines
|
|
18
|
+
<hr style="border: 1px solid black; margin: 0;">
|
|
19
|
+
|
|
20
|
+
## Update the code
|
|
21
|
+
```bash
|
|
22
|
+
git clone https://github.com/sdmlua/riverjoin_py
|
|
23
|
+
cd riverjoin_py
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Use the ```uv``` to work and update the code,
|
|
27
|
+
```bash
|
|
28
|
+
pip install uv
|
|
29
|
+
|
|
30
|
+
#Create a virtual env and start collabortaing the code
|
|
31
|
+
uv venv
|
|
32
|
+
|
|
33
|
+
#activate the virtual environment
|
|
34
|
+
source .venv/bin/activate
|
|
35
|
+
|
|
36
|
+
#Install all the dependencies and all development packages into it
|
|
37
|
+
uv pip install e .
|
|
38
|
+
uv pip install -e ".[dev]"
|
|
39
|
+
|
|
40
|
+
#Then add/edit modules under the src/ and run the code through the tests
|
|
41
|
+
#For instance
|
|
42
|
+
pytest tests/spatial_join.py
|
|
43
|
+
```
|
|
44
|
+
Once all changes are made, update the code style with ```black``` code formatter.
|
|
45
|
+
```bash
|
|
46
|
+
black .
|
|
47
|
+
```
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Framework for Spatially Joining two Hydrofabric Flowlines
|
|
2
|
+
<hr style="border: 1px solid black; margin: 0;">
|
|
3
|
+
|
|
4
|
+
## Update the code
|
|
5
|
+
```bash
|
|
6
|
+
git clone https://github.com/sdmlua/riverjoin_py
|
|
7
|
+
cd riverjoin_py
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Use the ```uv``` to work and update the code,
|
|
11
|
+
```bash
|
|
12
|
+
pip install uv
|
|
13
|
+
|
|
14
|
+
#Create a virtual env and start collabortaing the code
|
|
15
|
+
uv venv
|
|
16
|
+
|
|
17
|
+
#activate the virtual environment
|
|
18
|
+
source .venv/bin/activate
|
|
19
|
+
|
|
20
|
+
#Install all the dependencies and all development packages into it
|
|
21
|
+
uv pip install e .
|
|
22
|
+
uv pip install -e ".[dev]"
|
|
23
|
+
|
|
24
|
+
#Then add/edit modules under the src/ and run the code through the tests
|
|
25
|
+
#For instance
|
|
26
|
+
pytest tests/spatial_join.py
|
|
27
|
+
```
|
|
28
|
+
Once all changes are made, update the code style with ```black``` code formatter.
|
|
29
|
+
```bash
|
|
30
|
+
black .
|
|
31
|
+
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "riverjoin"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "This is a river join implementation in Python."
|
|
5
|
+
authors = [
|
|
6
|
+
{ name = "Supath Dhital", email = "sdhital@crimson.ua.edu" },
|
|
7
|
+
{ name = "Yixian Chen", email = "ychen223@ua.edu" }
|
|
8
|
+
]
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"geopandas",
|
|
13
|
+
"pathlib",
|
|
14
|
+
"fiona",
|
|
15
|
+
"folium",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.urls]
|
|
19
|
+
Homepage = "https://github.com/sdmlua/riverjoin_py"
|
|
20
|
+
|
|
21
|
+
[tool.setuptools]
|
|
22
|
+
package-dir = {"" = "src"}
|
|
23
|
+
|
|
24
|
+
[build-system]
|
|
25
|
+
requires = ["setuptools>=61.0"]
|
|
26
|
+
build-backend = "setuptools.build_meta"
|
|
27
|
+
|
|
28
|
+
[project.optional-dependencies]
|
|
29
|
+
dev = [
|
|
30
|
+
"pytest",
|
|
31
|
+
"black"
|
|
32
|
+
]
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
|
|
3
|
+
warnings.simplefilter("ignore")
|
|
4
|
+
|
|
5
|
+
from riverjoin.modules.project_initialization import setup_project
|
|
6
|
+
from riverjoin.modules.setup_hydrofabric import clip_flowlines
|
|
7
|
+
|
|
8
|
+
from riverjoin.modules.project_initialization import setup_project
|
|
9
|
+
from riverjoin.modules.setup_hydrofabric import clip_flowlines
|
|
10
|
+
from riverjoin.modules.flowlines_buffer import StreamNetworkExtractor
|
|
11
|
+
from riverjoin.modules.traced_downstream import traced_downstream
|
|
12
|
+
from riverjoin.modules.situation_checker import check_situation
|
|
13
|
+
from riverjoin.modules.perpendicularlines import (
|
|
14
|
+
create_nodes,
|
|
15
|
+
generate_perpendicular_lines,
|
|
16
|
+
PerpendicularCleaner,
|
|
17
|
+
SpatialJoinWithPerpendicularlines,
|
|
18
|
+
merge_and_drop_duplicates,
|
|
19
|
+
ReconstructDisconnectedSegments,
|
|
20
|
+
)
|
|
21
|
+
from riverjoin.modules.interactive_map import VizualizeOutputInteractively
|
|
22
|
+
from riverjoin.modules.compare_linelength import compare_linelength
|
|
23
|
+
from riverjoin.modules.attribute_transfer import (
|
|
24
|
+
NodeExtractor,
|
|
25
|
+
JoinNearestFlowLineAttributes,
|
|
26
|
+
AggregateJoinedFlowlines,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# utilities
|
|
31
|
+
from riverjoin.utilis import FlowlineFieldViewer
|
|
32
|
+
|
|
33
|
+
# Combined seamless workflow
|
|
34
|
+
from riverjoin.combined_workflow import run_riverjoin
|
|
35
|
+
|
|
36
|
+
__all__ = [
|
|
37
|
+
"setup_project",
|
|
38
|
+
"clip_flowlines",
|
|
39
|
+
"StreamNetworkExtractor",
|
|
40
|
+
"traced_downstream",
|
|
41
|
+
"check_situation",
|
|
42
|
+
"create_nodes",
|
|
43
|
+
"generate_perpendicular_lines",
|
|
44
|
+
"PerpendicularCleaner",
|
|
45
|
+
"SpatialJoinWithPerpendicularlines",
|
|
46
|
+
"merge_and_drop_duplicates",
|
|
47
|
+
"ReconstructDisconnectedSegments",
|
|
48
|
+
"VizualizeOutputInteractively",
|
|
49
|
+
"compare_linelength",
|
|
50
|
+
"NodeExtractor",
|
|
51
|
+
"JoinNearestFlowLineAttributes",
|
|
52
|
+
"AggregateJoinedFlowlines",
|
|
53
|
+
"FlowlineFieldViewer",
|
|
54
|
+
"run_riverjoin",
|
|
55
|
+
]
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This code is the compiled workflow where all the steps are combined into a single script for easier execution.
|
|
3
|
+
|
|
4
|
+
Author: Supath Dhital, Yixian Chen
|
|
5
|
+
Date: Nov 13, 2025
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Optional, Union, List
|
|
11
|
+
|
|
12
|
+
from riverjoin.modules.project_initialization import setup_project
|
|
13
|
+
|
|
14
|
+
from riverjoin.modules.setup_hydrofabric import clip_flowlines
|
|
15
|
+
from riverjoin.modules.flowlines_buffer import StreamNetworkExtractor
|
|
16
|
+
from riverjoin.modules.traced_downstream import traced_downstream
|
|
17
|
+
from riverjoin.modules.situation_checker import check_situation
|
|
18
|
+
from riverjoin.modules.perpendicularlines import (
|
|
19
|
+
create_nodes,
|
|
20
|
+
generate_perpendicular_lines,
|
|
21
|
+
PerpendicularCleaner,
|
|
22
|
+
SpatialJoinWithPerpendicularlines,
|
|
23
|
+
merge_and_drop_duplicates,
|
|
24
|
+
ReconstructDisconnectedSegments,
|
|
25
|
+
)
|
|
26
|
+
from riverjoin.modules.compare_linelength import compare_linelength
|
|
27
|
+
|
|
28
|
+
from riverjoin.modules.attribute_transfer import (
|
|
29
|
+
NodeExtractor,
|
|
30
|
+
JoinNearestFlowLineAttributes,
|
|
31
|
+
AggregateJoinedFlowlines,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# Combined workflow
|
|
36
|
+
class run_riverjoin:
|
|
37
|
+
"""
|
|
38
|
+
First it initializes the project structure using setup_project class.
|
|
39
|
+
then Setup the hydrofabric--> which includes clipping the flowlines based on user defined boundary or bbox
|
|
40
|
+
the extract the flowlines with multiple steps including buffer intersection, tracing downstream disconnected segments,
|
|
41
|
+
situation check, creating perpendicular nodes, generating perpendicular lines, cleaning the perpendicular lines,
|
|
42
|
+
spatial join with perpendicular lines, merging and dropping duplicates, reconstructing disconnected segments if any.
|
|
43
|
+
finally visualizing the output interactively.
|
|
44
|
+
|
|
45
|
+
And, Finally attribute will be transferred from one network to another.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
def __init__(
|
|
49
|
+
self,
|
|
50
|
+
join_fl: str,
|
|
51
|
+
target_fl: str,
|
|
52
|
+
unique_id: str,
|
|
53
|
+
unique_id_nextDown: str,
|
|
54
|
+
target_reach_unique_id_field: str,
|
|
55
|
+
join_fl_layer: Optional[str] = None,
|
|
56
|
+
target_fl_layer: Optional[str] = None,
|
|
57
|
+
boundary: Optional[str] = None,
|
|
58
|
+
boundary_layer: Optional[str] = None,
|
|
59
|
+
output_clip_layer: Optional[str] = None,
|
|
60
|
+
identifier: Optional[str] = None,
|
|
61
|
+
node_output_layer: Optional[str] = None,
|
|
62
|
+
strm_order_field: Optional[str] = None,
|
|
63
|
+
filter_eqn: Optional[Union[str, List[str]]] = None,
|
|
64
|
+
node_number: Optional[int] = None,
|
|
65
|
+
node_spacing: Optional[float] = None,
|
|
66
|
+
transfer_attributes: bool = True,
|
|
67
|
+
buffer_distance: int = 100,
|
|
68
|
+
spacing_join_fl: float = 500,
|
|
69
|
+
perp_line_length: float = 600,
|
|
70
|
+
min_join_count: int = 5,
|
|
71
|
+
min_strm_order: int = 2,
|
|
72
|
+
):
|
|
73
|
+
self.join_fl = join_fl
|
|
74
|
+
self.target_fl = target_fl
|
|
75
|
+
self.join_fl_layer = join_fl_layer
|
|
76
|
+
self.target_fl_layer = target_fl_layer
|
|
77
|
+
self.boundary = boundary
|
|
78
|
+
self.boundary_layer = boundary_layer
|
|
79
|
+
self.output_clip_layer = output_clip_layer
|
|
80
|
+
self.unique_id = unique_id
|
|
81
|
+
self.unique_id_nextDown = unique_id_nextDown
|
|
82
|
+
self.target_reach_unique_id_field = target_reach_unique_id_field
|
|
83
|
+
self.buffer_distance = buffer_distance
|
|
84
|
+
self.spacing = spacing_join_fl
|
|
85
|
+
self.node_spacing = node_spacing
|
|
86
|
+
self.node_number = node_number
|
|
87
|
+
self.perp_line_length = perp_line_length
|
|
88
|
+
self.identifier = identifier
|
|
89
|
+
self.node_output_layer = node_output_layer
|
|
90
|
+
self.min_join_count = min_join_count
|
|
91
|
+
self.min_strm_order = min_strm_order
|
|
92
|
+
self.strm_order_field = strm_order_field
|
|
93
|
+
self.filter_eqn = filter_eqn
|
|
94
|
+
self.transfer_attributes = transfer_attributes
|
|
95
|
+
|
|
96
|
+
# Initialize project structure
|
|
97
|
+
self.project_paths = setup_project()
|
|
98
|
+
self.output_fl = self.project_paths.output_reach_gpkg
|
|
99
|
+
self.extracted_fl = self.project_paths.output_final_reach_gpkg
|
|
100
|
+
|
|
101
|
+
# Clip flowlines
|
|
102
|
+
clip_flowlines(
|
|
103
|
+
join_fl=self.join_fl,
|
|
104
|
+
target_fl=self.target_fl,
|
|
105
|
+
join_fl_layer=self.join_fl_layer,
|
|
106
|
+
target_fl_layer=self.target_fl_layer,
|
|
107
|
+
boundary=self.boundary,
|
|
108
|
+
boundary_layer=self.boundary_layer,
|
|
109
|
+
output_clip_layer=self.output_clip_layer,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# Buffer intersection
|
|
113
|
+
StreamNetworkExtractor(
|
|
114
|
+
join_fl=self.join_fl,
|
|
115
|
+
unique_id=self.unique_id,
|
|
116
|
+
buffer_distance=self.buffer_distance,
|
|
117
|
+
join_fl_layer=self.join_fl_layer,
|
|
118
|
+
output_clip_layer=self.output_clip_layer,
|
|
119
|
+
identifier=self.identifier,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
# Check the situation of the extraction--> maybe need to terminate the process here if no or all flowlines got extracted!!
|
|
123
|
+
cs = check_situation(
|
|
124
|
+
identifier=self.identifier,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
# Run the next steps or terminate based on situation
|
|
128
|
+
if cs.situation == "extract_upstream_others":
|
|
129
|
+
# tracing the downstream segments
|
|
130
|
+
traced_downstream(
|
|
131
|
+
unique_id=self.unique_id,
|
|
132
|
+
unique_id_nextDown=self.unique_id_nextDown,
|
|
133
|
+
join_fl=self.join_fl,
|
|
134
|
+
join_fl_layer=self.join_fl_layer,
|
|
135
|
+
identifier=self.identifier,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# create nodes for perpendicular lines for further extraction
|
|
139
|
+
create_nodes(
|
|
140
|
+
target_reach_unique_id_field=self.target_reach_unique_id_field,
|
|
141
|
+
output_clip_layer=self.output_clip_layer,
|
|
142
|
+
identifier=self.identifier,
|
|
143
|
+
spacing=self.spacing,
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# Generate perpendicular lines along the created nodes
|
|
147
|
+
generate_perpendicular_lines(
|
|
148
|
+
spacing=self.spacing,
|
|
149
|
+
perp_line_length=self.perp_line_length,
|
|
150
|
+
identifier=self.identifier,
|
|
151
|
+
node_output_layer=self.node_output_layer,
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
# Perpendicular lines cleaning
|
|
155
|
+
PerpendicularCleaner(
|
|
156
|
+
spacing=self.spacing,
|
|
157
|
+
perp_line_length=self.perp_line_length,
|
|
158
|
+
identifier=self.identifier,
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
# Spatial join with perpendicular lines
|
|
162
|
+
SpatialJoinWithPerpendicularlines(
|
|
163
|
+
join_fl=self.join_fl,
|
|
164
|
+
unique_id=self.unique_id,
|
|
165
|
+
min_join_count=self.min_join_count,
|
|
166
|
+
min_strm_order=self.min_strm_order,
|
|
167
|
+
join_fl_layer=self.join_fl_layer,
|
|
168
|
+
strm_order_field=self.strm_order_field,
|
|
169
|
+
identifier=self.identifier,
|
|
170
|
+
filter_eqn=self.filter_eqn,
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
# Merging and dropping duplicates
|
|
174
|
+
merge_and_drop_duplicates(
|
|
175
|
+
join_fl=self.join_fl,
|
|
176
|
+
join_fl_layer=self.join_fl_layer,
|
|
177
|
+
identifier=self.identifier,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
# Reconstructing disconnected segments if any
|
|
181
|
+
ReconstructDisconnectedSegments(
|
|
182
|
+
unique_id=self.unique_id,
|
|
183
|
+
unique_id_nextDown=self.unique_id_nextDown,
|
|
184
|
+
join_fl=self.join_fl,
|
|
185
|
+
join_fl_layer=self.join_fl_layer,
|
|
186
|
+
identifier=self.identifier,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
# Compare the basic statistics of line length between the extracted and target flowlines
|
|
190
|
+
compare_linelength(
|
|
191
|
+
identifier=self.identifier,
|
|
192
|
+
output_fl=self.output_fl,
|
|
193
|
+
extracted_fl=self.extracted_fl,
|
|
194
|
+
output_layer=self.output_clip_layer,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
# Transfer the attribute from one network to another
|
|
198
|
+
if self.transfer_attributes:
|
|
199
|
+
NodeExtractor(
|
|
200
|
+
target_network_unique_id_field=self.unique_id,
|
|
201
|
+
identifier=self.identifier,
|
|
202
|
+
spacing=self.node_spacing,
|
|
203
|
+
node_number=self.node_number,
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
JoinNearestFlowLineAttributes(
|
|
207
|
+
target_network_unique_id_field=self.unique_id,
|
|
208
|
+
identifier=self.identifier,
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
AggregateJoinedFlowlines(
|
|
212
|
+
target_network_unique_id_field=self.unique_id,
|
|
213
|
+
join_network_unique_id_field=self.target_reach_unique_id_field,
|
|
214
|
+
identifier=self.identifier,
|
|
215
|
+
)
|
|
216
|
+
else:
|
|
217
|
+
id_msg = f" for {self.identifier}" if self.identifier is not None else ""
|
|
218
|
+
print(f"Terminating further processing as '{cs.situation}'{id_msg}.")
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from riverjoin.modules.project_initialization import setup_project
|
|
2
|
+
from riverjoin.modules.setup_hydrofabric import clip_flowlines
|
|
3
|
+
|
|
4
|
+
from riverjoin.modules.project_initialization import setup_project
|
|
5
|
+
from riverjoin.modules.setup_hydrofabric import clip_flowlines
|
|
6
|
+
from riverjoin.modules.flowlines_buffer import StreamNetworkExtractor
|
|
7
|
+
from riverjoin.modules.traced_downstream import traced_downstream
|
|
8
|
+
from riverjoin.modules.situation_checker import check_situation
|
|
9
|
+
from riverjoin.modules.perpendicularlines import (
|
|
10
|
+
create_nodes,
|
|
11
|
+
generate_perpendicular_lines,
|
|
12
|
+
PerpendicularCleaner,
|
|
13
|
+
SpatialJoinWithPerpendicularlines,
|
|
14
|
+
merge_and_drop_duplicates,
|
|
15
|
+
ReconstructDisconnectedSegments,
|
|
16
|
+
)
|
|
17
|
+
from riverjoin.modules.interactive_map import VizualizeOutputInteractively
|
|
18
|
+
from riverjoin.modules.compare_linelength import compare_linelength
|
|
19
|
+
from riverjoin.modules.attribute_transfer import (
|
|
20
|
+
NodeExtractor,
|
|
21
|
+
JoinNearestFlowLineAttributes,
|
|
22
|
+
AggregateJoinedFlowlines,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# utilities
|
|
27
|
+
from riverjoin.utilis import FlowlineFieldViewer
|
|
28
|
+
|
|
29
|
+
__all__ = [
|
|
30
|
+
"setup_project",
|
|
31
|
+
"clip_flowlines",
|
|
32
|
+
"StreamNetworkExtractor",
|
|
33
|
+
"traced_downstream",
|
|
34
|
+
"check_situation",
|
|
35
|
+
"create_nodes",
|
|
36
|
+
"generate_perpendicular_lines",
|
|
37
|
+
"PerpendicularCleaner",
|
|
38
|
+
"SpatialJoinWithPerpendicularlines",
|
|
39
|
+
"merge_and_drop_duplicates",
|
|
40
|
+
"ReconstructDisconnectedSegments",
|
|
41
|
+
"VizualizeOutputInteractively",
|
|
42
|
+
"compare_linelength",
|
|
43
|
+
"NodeExtractor",
|
|
44
|
+
"JoinNearestFlowLineAttributes",
|
|
45
|
+
"AggregateJoinedFlowlines",
|
|
46
|
+
"FlowlineFieldViewer",
|
|
47
|
+
]
|