Skip to content

Commit 592aef2

Browse files
authored
dedicated minimal tests -- nodes.get_components() (#57)
* dedicated testing for nodes.get_components() * add lil typehint + docstring for nodes._status()
1 parent 33104e8 commit 592aef2

File tree

3 files changed

+103
-5
lines changed

3 files changed

+103
-5
lines changed

sgeop/geometry.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,13 @@ def voronoi_skeleton(
104104
secondary_snap_to: None | gpd.GeoSeries = None,
105105
clip_limit: None | int = 2,
106106
consolidation_tolerance: None | float = None,
107-
):
107+
) -> tuple[np.ndarray]:
108108
"""
109109
Returns average geometry.
110110
111111
Parameters
112112
----------
113-
lines : array_like
113+
lines : list | numpy.ndarray | geopandas.GeoSeries
114114
LineStrings connected at endpoints. If ``poly`` is passed in, ``lines``
115115
must be a ``geopandas.GeoSeries``.
116116
poly : None | shapely.Polygon = None
@@ -136,8 +136,10 @@ def voronoi_skeleton(
136136
137137
Returns
138138
-------
139-
numpy.ndarray
139+
edgelines : numpy.ndarray
140140
Array of averaged geometries.
141+
splitters : numpy.ndarray
142+
Split points.
141143
"""
142144
if buffer is None:
143145
buffer = max_segment_length * 20

sgeop/nodes.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,37 @@ def _snap_n_split(e: shapely.LineString, s: shapely.Point, tol: float) -> np.nda
7474
return _lines_split[~shapely.is_empty(_lines_split)]
7575

7676

77-
def _status(x):
77+
def _status(x: pd.Series) -> str:
78+
"""Determine the status of edge line(s)."""
7879
if len(x) == 1:
7980
return x.iloc[0]
8081
if "new" in x:
8182
return "new"
8283
return "changed"
8384

8485

85-
def get_components(edgelines, ignore=None):
86+
def get_components(
87+
edgelines: list | np.ndarray | gpd.GeoSeries,
88+
ignore: None | gpd.GeoSeries = None,
89+
) -> np.ndarray:
90+
"""Associate edges with connected component labels and return.
91+
92+
Parameters
93+
----------
94+
edgelines : list | np.ndarray | gpd.GeoSeries
95+
Collection of line objects.
96+
ignore : None | gpd.GeoSeries = None
97+
Nodes to ignore when labeling components.
98+
99+
Returns
100+
-------
101+
np.ndarray
102+
Edge connected component labels.
103+
104+
Notes
105+
-----
106+
See [https://github.com/uscuni/sgeop/issues/56] for detailed explanation of output.
107+
"""
86108
edgelines = np.array(edgelines)
87109
start_points = shapely.get_point(edgelines, 0)
88110
end_points = shapely.get_point(edgelines, -1)

sgeop/tests/test_nodes.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,77 @@ def test_split(split_points, cleaned_roads, known):
180180
def test_snap_n_split(edge, split_point, tol, known):
181181
observed = sgeop.nodes._snap_n_split(edge, split_point, tol)
182182
numpy.testing.assert_array_equal(observed, known)
183+
184+
185+
line_3_4 = shapely.LineString((point_3, point_4))
186+
line_4_5 = shapely.LineString((point_4, point_5))
187+
line_234 = shapely.LineString((point_2, point_3, point_4))
188+
189+
edgeline_types_get_components = [
190+
[line_1_2, line_2_4],
191+
numpy.array([line_1_2, line_3_4]),
192+
geopandas.GeoSeries([line_1_2, line_234]),
193+
[line_1_2, line_2_4] + [line_4_5],
194+
]
195+
196+
ignore_types_get_components = [
197+
None,
198+
point_2,
199+
[point_2],
200+
numpy.array([point_3]),
201+
geopandas.GeoSeries([point_3]),
202+
]
203+
204+
cases_types_get_components = [
205+
list(c)
206+
for c in itertools.product(
207+
edgeline_types_get_components, ignore_types_get_components
208+
)
209+
]
210+
211+
known_get_components = [
212+
[0, 0],
213+
[2.0, 3.0],
214+
[2.0, 3.0],
215+
[0, 0],
216+
[0, 0],
217+
[2.0, 3.0],
218+
[2.0, 3.0],
219+
[2.0, 3.0],
220+
[2.0, 3.0],
221+
[2.0, 3.0],
222+
[0, 0],
223+
[2.0, 3.0],
224+
[2.0, 3.0],
225+
[0, 0],
226+
[0, 0],
227+
[0, 0, 0],
228+
[1.0, 0.0, 0.0],
229+
[1.0, 0.0, 0.0],
230+
[0, 0, 0],
231+
[0, 0, 0],
232+
]
233+
234+
cases_get_components = [
235+
(*arg12, arg3)
236+
for arg12, arg3 in list(
237+
zip(cases_types_get_components, known_get_components, strict=True)
238+
)
239+
]
240+
241+
242+
t1_get_components = ["list", "ndarray", "GeoSeries", "list"]
243+
t2_get_components = ["NoneType", "Point", "list", "ndarray", "GeoSeries"]
244+
case_ids_get_components = [
245+
"-".join(c) for c in itertools.product(t1_get_components, t2_get_components)
246+
]
247+
248+
249+
@pytest.mark.parametrize(
250+
"edgelines,ignore,known",
251+
cases_get_components,
252+
ids=case_ids_get_components,
253+
)
254+
def test_get_components(edgelines, ignore, known):
255+
observed = sgeop.nodes.get_components(edgelines, ignore=ignore)
256+
numpy.testing.assert_array_equal(observed, known)

0 commit comments

Comments
 (0)