Skip to content

Commit

Permalink
Improved has_overlaps checks and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
geographika committed May 26, 2023
1 parent 53220ea commit 74c410f
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 24 deletions.
29 changes: 21 additions & 8 deletions tests/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,11 +414,11 @@ def test_get_path_length():

def test_has_overlaps():
edges = [
Edge(0, 1, "A", {"EDGE_ID": 1}),
Edge(1, 2, "B", {"EDGE_ID": 2}),
Edge(2, 3, "C", {"EDGE_ID": 3}),
Edge(2, 3, "C", {"EDGE_ID": 2}),
Edge(2, 3, "C", {"EDGE_ID": 4}),
Edge(0, 1, "A", {"EDGE_ID": 1, "OFFSET": 0, "LEN_": 10}),
Edge(1, 2, "B", {"EDGE_ID": 2, "OFFSET": 0, "LEN_": 10}),
Edge(2, 3, "C", {"EDGE_ID": 3, "OFFSET": 0, "LEN_": 10}),
Edge(2, 3, "C", {"EDGE_ID": 2, "OFFSET": 0, "LEN_": 10}),
Edge(2, 3, "C", {"EDGE_ID": 4, "OFFSET": 0, "LEN_": 10}),
]
assert functions.has_overlaps(edges) is True

Expand All @@ -444,6 +444,17 @@ def test_has_no_overlaps_loop():
assert functions.has_overlaps(edges) is False


def test_has_no_overlaps_loop_with_split():
edges = [
Edge(0, 1, "A", {"EDGE_ID": 1, "OFFSET": 5, "LEN_": 10}),
Edge(1, 2, "B", {"EDGE_ID": 2, "OFFSET": 0, "LEN_": 10}),
Edge(1, 2, "B", {"EDGE_ID": 2, "OFFSET": 10, "LEN_": 10}),
Edge(2, 3, "C", {"EDGE_ID": 3, "OFFSET": 0, "LEN_": 10}),
Edge(3, 0, "C", {"EDGE_ID": 4, "OFFSET": 0, "LEN_": 5}),
]
assert functions.has_overlaps(edges) is False


def test_doctest():
import doctest

Expand All @@ -456,9 +467,9 @@ def test_doctest():
# test_edges_to_graph()
# test_get_edges_from_nodes()
# test_edges_to_graph()
test_get_shortest_edge()
test_get_shortest_edge_identical()
test_get_shortest_edge_mixed_keys()
# test_get_shortest_edge()
# test_get_shortest_edge_identical()
# test_get_shortest_edge_mixed_keys()
# test_get_unique_ordered_list()
# test_get_edges_from_node_pair()
# test_to_edge()
Expand All @@ -471,4 +482,6 @@ def test_doctest():
# test_get_edges_from_nodes_non_unique()
# test_has_no_overlaps()
# test_has_no_overlaps_loop()
# test_has_overlaps()
test_has_no_overlaps_loop_with_split()
print("Done!")
3 changes: 2 additions & 1 deletion wayfarer.pyproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>f8ac0630-98af-462b-b7ee-5688d6183c85</ProjectGuid>
<ProjectHome>.</ProjectHome>
<StartupFile>tests\test_splitting.py</StartupFile>
<StartupFile>tests\test_functions.py</StartupFile>
<SearchPath>
</SearchPath>
<WorkingDirectory>.</WorkingDirectory>
Expand Down Expand Up @@ -144,6 +144,7 @@
<Content Include="dev_setup.ps1" />
<Content Include="build_docs.ps1" />
<Content Include="LICENSE" />
<Content Include="requirements.demo.txt" />
<Content Include="run_local.ps1" />
<Content Include="README.rst" />
<Content Include="requirements.txt">
Expand Down
2 changes: 1 addition & 1 deletion wayfarer/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import NamedTuple


__version__ = "0.9.3"
__version__ = "0.9.4"

LENGTH_FIELD = "LEN_"
EDGE_ID_FIELD = "EDGE_ID"
Expand Down
35 changes: 21 additions & 14 deletions wayfarer/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
NODEID_FROM_FIELD,
NODEID_TO_FIELD,
WITH_DIRECTION_FIELD,
OFFSET_FIELD,
Edge,
)

Expand Down Expand Up @@ -612,27 +613,33 @@ def get_multiconnected_nodes(edges, connections=2):
def has_overlaps(edges: list[Edge]) -> bool:
"""
Checks if the provided list of edges has overlaps
where the same edge id is repeated in the sequence.
Edge ids can be adjacent e.g. 1,2,2,3 returns False
and the same edge id can be found at the start and end of the sequence
e.g. 1,2,3,1 returns False
If an edge is split but the measures don't overlap then this will return False
The same edge id can be found at the start and end of the sequence if there is
no overlap of measures
>>> edges = [Edge(0, 1, "A", {"EDGE_ID": 1}), Edge(1, 2, "B", {"EDGE_ID": 2})]
>>> edges = [Edge(0, 1, "A", {"EDGE_ID": 1, "OFFSET": 0, "LEN_": 10}), \
Edge(1, 2, "B", {"EDGE_ID": 2, "OFFSET": 0, "LEN_": 10})]
>>> has_overlaps(edges)
False
"""
# get the edge id from the attributes rather than the edge key in case
# there are split edges which will have modified keys

edge_ids = [e.attributes[EDGE_ID_FIELD] for e in edges]
sorted_edges = sorted(edges, key=lambda e: e.attributes[EDGE_ID_FIELD])
grouped_edges = itertools.groupby(
sorted_edges, key=lambda e: e.attributes[EDGE_ID_FIELD]
)

grouped_edge_ids = [k for k, g in itertools.groupby(edge_ids)]
unique_edge_count = len(set(edge_ids))
for _, edge_group in grouped_edges:
for edge1, edge2 in itertools.combinations(edge_group, 2):

if edge_ids[0] == edge_ids[-1]:
unique_edge_count += 1 # allow looping back onto start edge
from_m1 = edge1.attributes.get(OFFSET_FIELD, 0)
to_m1 = from_m1 + edge1.attributes.get(LENGTH_FIELD, 0)

if len(grouped_edge_ids) > unique_edge_count:
return True
else:
return False
from_m2 = edge2.attributes.get(OFFSET_FIELD, 0)
to_m2 = from_m2 + edge2.attributes.get(LENGTH_FIELD, 0)

if max(from_m1, from_m2) < min(to_m1, to_m2):
return True

return False

0 comments on commit 74c410f

Please sign in to comment.