Newer
Older
# imports
# standard
import random
from math import isclose
import uuid
# local, external
import osmnx as ox
import networkx as nx
from shapely.geometry import Point, LineString
# local, internal
import src.topupopt.data.gis.identify as gis_iden
import src.topupopt.data.gis.osm as gis_osm
# *****************************************************************************
# *****************************************************************************
class TestGisIdentify:
# *************************************************************************
# *************************************************************************
def straight_path_validator(
self,
network: nx.MultiDiGraph,
path: list,
excluded_nodes: list,
consider_reversed_edges: bool,
ignore_self_loops: bool,
):
# find out the unique nodes
set_nodes = set(path)
# at least three nodes
assert len(path) >= 3
# no repeated nodes unless they appear first and last
for node in set_nodes:
# count the nodes
node_count = path.count(node)
if node_count >= 3:
assert False
elif node_count == 2:
# cycle: the first and last nodes must match
assert path[0] == path[-1] and path[0] == node
# cycle: make sure
# no excluded nodes in the intermediate positions
for node in excluded_nodes:
assert node not in path[1:-1]
# intermediate nodes can only have two neighbours
for node_key in path[1:-1]:
assert (
len(set(gis_iden.neighbours(network, node_key, ignore_self_loops=True)))
== 2
)
# end nodes need to have at least one neighbour, except in loops,
# wherein they need to have two neighbours
if path[0] == path[-1]:
# end nodes in loops need to have at least two neighbours
assert (
len(set(gis_iden.neighbours(network, path[0], ignore_self_loops=True)))
>= 2
)
else:
# end nodes need to have at least one neighbour
assert (
len(set(gis_iden.neighbours(network, path[0], ignore_self_loops=True)))
>= 1
)
assert (
len(set(gis_iden.neighbours(network, path[-1], ignore_self_loops=True)))
>= 1
)
# if ignore_self_loops=False, intermediate nodes cannot have self-loops
if not ignore_self_loops:
for node in path[1:-1]:
assert not network.has_edge(node, node)
# if path[0] == path[-1]:
# # loop, applies to all nodes
# for node in path:
# assert not network.has_edge(node, node)
# else:
# # not a loop, applies only to intermediate nodes
# for node in path[1:-1]:
# assert not network.has_edge(node, node)
network, path, consider_reversed_edges=consider_reversed_edges
)
# make sure it is a straight path
assert gis_iden.is_path_straight(
consider_reversed_edges=consider_reversed_edges,
# *************************************************************************
# *************************************************************************
def test_finding_simplifiable_paths_osmnx(self):
# network should be a OSM-nx formatted graph
network = ox.graph_from_point(
custom_filter='["highway"~"residential|tertiary|unclassified|service"]',
# *********************************************************************
# *********************************************************************
consider_reversed_edges = False
ignore_self_loops = False
# paths
paths = gis_iden.find_simplifiable_paths(
excluded_nodes=[],
consider_reversed_edges=consider_reversed_edges,
# verify the paths
for path in paths:
self.straight_path_validator(
consider_reversed_edges=consider_reversed_edges,
# *********************************************************************
# *********************************************************************
consider_reversed_edges = False
ignore_self_loops = True
# paths
paths = gis_iden.find_simplifiable_paths(
excluded_nodes=[],
consider_reversed_edges=consider_reversed_edges,
# verify the paths
for path in paths:
self.straight_path_validator(
consider_reversed_edges=consider_reversed_edges,
# *********************************************************************
# *********************************************************************
consider_reversed_edges = True
ignore_self_loops = False
# paths
paths = gis_iden.find_simplifiable_paths(
excluded_nodes=[],
consider_reversed_edges=consider_reversed_edges,
# verify the paths
for path in paths:
self.straight_path_validator(
consider_reversed_edges=consider_reversed_edges,
# *********************************************************************
# *********************************************************************
consider_reversed_edges = True
ignore_self_loops = True
# paths
paths = gis_iden.find_simplifiable_paths(
excluded_nodes=[],
consider_reversed_edges=consider_reversed_edges,
# verify the paths
for path in paths:
self.straight_path_validator(
consider_reversed_edges=consider_reversed_edges,
ignore_self_loops=ignore_self_loops,
)
# *********************************************************************
# *********************************************************************
# *************************************************************************
# *************************************************************************
def test_find_straight_path_empty_graph(self):
# test variations:
# 1) excluded nodes
# 2) self loops
# 3) reversed edges
# *********************************************************************
# *********************************************************************
# no reversed edges, no self loops, no excluded nodes
consider_reversed_edges = False
ignore_self_loops = False
# test path validator with non-path
error_raised = False
try:
assert not self.straight_path_validator(
consider_reversed_edges=consider_reversed_edges,
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
assert len(straight_paths) == 0
# *********************************************************************
# *********************************************************************
# no reversed edges, no self loops, no excluded nodes
consider_reversed_edges = False
ignore_self_loops = True
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# no reversed edges, no self loops, no excluded nodes
consider_reversed_edges = True
ignore_self_loops = False
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# no reversed edges, no self loops, no excluded nodes
consider_reversed_edges = True
ignore_self_loops = True
excluded_nodes = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
path = gis_iden._find_path_direction_insensitive(network, [], 0, False)
assert type(path) == list
assert len(path) == 1
assert repr(path) == repr([0])
# *************************************************************************
# *************************************************************************
def test_find_one_edge_path(self):
# *********************************************************************
# *********************************************************************
# *********************************************************************
# *********************************************************************
# *********************************************************************
# *********************************************************************
# no reversed edges, no self loops, no excluded nodes
ignore_self_loops = False
excluded_nodes = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# no reversed edges, allow self loops, no excluded nodes
ignore_self_loops = True
excluded_nodes = []
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# do not allow reversed edges, no self loops, excluded the middle node
ignore_self_loops = False
excluded_nodes = [1]
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# do not allow reversed edges, no self loops, excluded the start node
ignore_self_loops = False
excluded_nodes = [0]
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# do not allow reversed edges, no self loops, excluded the end node
ignore_self_loops = False
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# *********************************************************************
# *********************************************************************
# allow reversed edges, allow self loops, no excluded nodes
ignore_self_loops = True
excluded_nodes = []
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# allow reversed edges, no self loops, no excluded nodes
ignore_self_loops = False
excluded_nodes = []
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# allow reversed edges, no self loops, excluded the middle node
ignore_self_loops = False
excluded_nodes = [1]
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# allow reversed edges, no self loops, excluded the start node
ignore_self_loops = False
excluded_nodes = [0]
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# allow reversed edges, no self loops, excluded the end node
ignore_self_loops = False
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# *************************************************************************
# *************************************************************************
def test_find_one_edge_path_w_reversed_edge(self):
# *********************************************************************
# *********************************************************************
# *********************************************************************
# *********************************************************************
# *********************************************************************
# *********************************************************************
# no reversed edges, no self loops, no excluded nodes
ignore_self_loops = False
excluded_nodes = []
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# no reversed edges, allow self loops, no excluded nodes
ignore_self_loops = True
excluded_nodes = []
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# do not allow reversed edges, no self loops, excluded the middle node
ignore_self_loops = False
excluded_nodes = [1]
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# do not allow reversed edges, no self loops, excluded the start node
ignore_self_loops = False
excluded_nodes = [0]
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# do not allow reversed edges, no self loops, excluded the end node
ignore_self_loops = False
excluded_nodes = [2]
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# *********************************************************************
# *********************************************************************
# allow reversed edges, allow self loops, no excluded nodes
ignore_self_loops = True
excluded_nodes = []
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# allow reversed edges, no self loops, no excluded nodes
ignore_self_loops = False
excluded_nodes = []
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# allow reversed edges, no self loops, excluded the middle node
ignore_self_loops = False
excluded_nodes = [1]
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# allow reversed edges, no self loops, excluded the start node
ignore_self_loops = False
excluded_nodes = [0]
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# allow reversed edges, no self loops, excluded the end node
ignore_self_loops = False
excluded_nodes = [2]
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# *************************************************************************
# *************************************************************************
def test_find_simple_straight_path(self):
# *********************************************************************
# *********************************************************************
# *********************************************************************
# *********************************************************************
# *********************************************************************
# *********************************************************************
# no reversed edges, no self loops, no excluded nodes
ignore_self_loops = False
excluded_nodes = []
true_straight_paths = [[0, 1, 2]]
assert len(straight_paths) == len(true_straight_paths)
for straight_path in straight_paths:
assert straight_path in true_straight_paths
self.straight_path_validator(
consider_reversed_edges=consider_reversed_edges,
# *********************************************************************
# *********************************************************************
# no reversed edges, allow self loops, no excluded nodes
ignore_self_loops = True
excluded_nodes = []
true_straight_paths = [[0, 1, 2]]
assert len(straight_paths) == len(true_straight_paths)
for straight_path in straight_paths:
assert straight_path in true_straight_paths
self.straight_path_validator(
consider_reversed_edges=consider_reversed_edges,
# *********************************************************************
# *********************************************************************
# do not allow reversed edges, no self loops, excluded the middle node
ignore_self_loops = False
excluded_nodes = [1]
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# do not allow reversed edges, no self loops, excluded the start node
ignore_self_loops = False
excluded_nodes = [0]
true_straight_paths = [[0, 1, 2]]
assert len(straight_paths) == len(true_straight_paths)
for straight_path in straight_paths:
assert straight_path in true_straight_paths
self.straight_path_validator(
consider_reversed_edges=consider_reversed_edges,
# *********************************************************************
# *********************************************************************
# do not allow reversed edges, no self loops, excluded the end node
ignore_self_loops = False
excluded_nodes = [2]
true_straight_paths = [[0, 1, 2]]
assert len(straight_paths) == len(true_straight_paths)
for straight_path in straight_paths:
assert straight_path in true_straight_paths
self.straight_path_validator(
consider_reversed_edges=consider_reversed_edges,
# *********************************************************************
# *********************************************************************
# *********************************************************************
# *********************************************************************
# allow reversed edges, allow self loops, no excluded nodes
ignore_self_loops = True
excluded_nodes = []
assert len(straight_paths) == len(true_straight_paths) - 1
for straight_path in straight_paths:
assert straight_path in true_straight_paths
self.straight_path_validator(
consider_reversed_edges=consider_reversed_edges,
# *********************************************************************
# *********************************************************************
# allow reversed edges, no self loops, no excluded nodes
ignore_self_loops = False
excluded_nodes = []
assert len(straight_paths) == len(true_straight_paths) - 1
for straight_path in straight_paths:
assert straight_path in true_straight_paths
self.straight_path_validator(
consider_reversed_edges=consider_reversed_edges,
# *********************************************************************
# *********************************************************************
# allow reversed edges, no self loops, excluded the middle node
ignore_self_loops = False
excluded_nodes = [1]
true_straight_paths = []
assert len(straight_paths) == len(true_straight_paths)
# *********************************************************************
# *********************************************************************
# allow reversed edges, no self loops, excluded the start node
ignore_self_loops = False
excluded_nodes = [0]
assert len(straight_paths) == len(true_straight_paths) - 1
for straight_path in straight_paths:
assert straight_path in true_straight_paths
self.straight_path_validator(
consider_reversed_edges=consider_reversed_edges,
# *********************************************************************
# *********************************************************************
# allow reversed edges, no self loops, excluded the end node
ignore_self_loops = False
excluded_nodes = [2]
assert len(straight_paths) == len(true_straight_paths) - 1
for straight_path in straight_paths:
assert straight_path in true_straight_paths
self.straight_path_validator(
consider_reversed_edges=consider_reversed_edges,
# *********************************************************************
# *********************************************************************
# *************************************************************************
# *************************************************************************
def test_find_simple_straight_path_with_antiparallel_edge(self):
# *********************************************************************
# *********************************************************************
network.add_edges_from([(0, 1, 0), (1, 2, 0), (2, 1, 0)])
# *********************************************************************
# *********************************************************************
# *********************************************************************
# *********************************************************************
# no reversed edges, no self loops, no excluded nodes
ignore_self_loops = False
excluded_nodes = []
true_straight_paths = [[0, 1, 2]]
assert len(straight_paths) == len(true_straight_paths)
for straight_path in straight_paths:
assert straight_path in true_straight_paths
self.straight_path_validator(
consider_reversed_edges=consider_reversed_edges,
# *********************************************************************
# *********************************************************************
# no reversed edges, allow self loops, no excluded nodes
ignore_self_loops = True