Plant.py arbeitet jetzt mit dem str tree zusammen mit der bbox.

This commit is contained in:
2025-05-26 14:36:20 +02:00
parent e347794373
commit 761bf22636
5 changed files with 265 additions and 395 deletions
+261 -390
View File
@@ -110,7 +110,7 @@ class NodeIDs():
def show(self):
return self._id2cord
class RackIDs():
def __init__(self, tol_snap = 200):
def __init__(self, tol_snap = 200.0):
self._point2rack = dict()
self._rack2begend = dict()
# Toleranzen zur Rack anbindung aneinander (Rack Snap)
@@ -267,7 +267,7 @@ class Anlage():
"""
def __init__(self, tol_snap=200, snap_step=10, tol_connect=1000, tol_connect_step=50):
def __init__(self, tol_snap=200.0, snap_step=10.0, tol_connect=1000.0, tol_connect_step=50.0):
# Container für alle Racks
self._racks = RackIDs(tol_snap=tol_snap)
# zuordnung zwischen KnotenID und Punkt
@@ -288,6 +288,8 @@ class Anlage():
self._connect_step = tol_connect_step
# Infos zum zeichnen des Graphen
self._node_positions = dict()
# falls man die rack zu den Sensorpunkten abfragen möchte, ist ein STR Baum nötig
self._rack_tree = None
def set_racks(self, racks:dict[str, list[Point]]):
r"""
@@ -362,21 +364,6 @@ class Anlage():
die Rückgabe enthält ein Tuple, welche Sensoren keinem Rack zugeordnet werden konnten
'''
return self.connect_equipment_to_racks(self._sensors, self._sensor_onpoints)
'''
errors = list()
for sname, pos in self._sensors.items():
rack_borders = self._racks.get_racks_borders()
onpoint, rack_name = self.find_nearest_rack_from_point(self._tol_connect, self._connect_step, pos, rack_borders)
if onpoint == None or rack_name == None:
errors.append((sname, pos))
continue
self._sensor_onpoints[sname] = (onpoint, rack_name)
self.add_point_to_rack(onpoint, rack_name)
# Füge "virtuelle Racks" von Sensor zu Aufpunkt von Sensor auf Rack hinzu.
vrackname = f"v-{sname}-{rack_name}"
self._racks.add_rack(pos, onpoint, vrackname)
return errors
'''
def add_distributor(self, dname: str, pos:Point):
self._distributors[dname] = pos
@@ -393,21 +380,6 @@ class Anlage():
die Rückage enthält ein Tuple, welche Unterverteiler keinem Rack zugeordnet werden konnten
'''
return self.connect_equipment_to_racks(self._distributors, self._distributors_onpoints)
'''
errors = list()
for dname, pos in self._distributors.items():
rack_borders = self._racks.get_racks_borders()
onpoint, rack_name = self.find_nearest_rack_from_point(self._tol_connect, self._connect_step, pos, rack_borders)
if onpoint == None or rack_name == None:
errors.append((dname, pos))
continue
self._distributors_onpoints[dname] = (onpoint, rack_name)
self.add_point_to_rack(onpoint, rack_name)
# Füge "virtuelle Racks" von Sensor zu Aufpunkt von Sensor auf Rack hinzu.
drackname = f"d-{dname}-{rack_name}"
self._racks.add_rack(pos, onpoint, drackname)
return errors
'''
def join_racks(self):
self._racks.join_racks()
@@ -420,40 +392,20 @@ class Anlage():
self._rack_lines.append(line)
self._rack_map[line] = r_name
self._rack_tree = STRtree(self._rack_lines)
def find_nearest_rack_from_point_tree(self, max_dist, sensor:Point) -> tuple[Point, str]:
if not hasattr(self, "_rack_tree"):
self._build_rack_strtree()
result = self._rack_tree.query_nearest(sensor, return_distance=True)
if result == None:
return None, None
index_array, dist_array = result
nearest_index = index_array[0]
distance = dist_array[0]
#nearest_line, distance = result
if distance > max_dist:
return None, None
nearest_line = self._rack_lines[nearest_index]
rack_name = self._rack_map[nearest_line]
nearest_point = nearest_line.interpolate(nearest_line.project(sensor))
return(nearest_point, rack_name)
def find_nearest_rack_from_point_STR_bbox(self, max_dist, sensor:Point) -> tuple[Point, str]:
if not hasattr(self, "_rack_tree"):
if self._rack_tree is None:
self._build_rack_strtree()
minx, miny, maxx, maxy = sensor.x - max_dist, sensor.y - max_dist, sensor.x + max_dist, sensor.y + max_dist
bbox = box(minx, miny, maxx, maxy)
candidates = self._rack_tree.query(box)
if not candidates:
return None, None
candidates = self._rack_tree.query(bbox)
if len(candidates) == 0:
raise LookupError("no candidates in box found")
candidates = [self._rack_lines[idx] for idx in candidates]
best_dist = max_dist
for line in candidates:
dist = sensor.distance(line)
if dist < best_dist:
@@ -461,7 +413,7 @@ class Anlage():
best_line = line
if best_dist > max_dist:
return None, None
raise LookupError("no line in correct distance found")
rack_name = self._rack_map[best_line]
nearest_point = best_line.interpolate(best_line.project(sensor))
@@ -475,11 +427,12 @@ class Anlage():
'''
errors = []
for name, pos in equipment.items():
onpoint, rackname = self.find_nearest_rack_from_point_STR_bbox(self._tol_connect, pos)
if onpoint == None or rackname == None:
try:
onpoint, rackname = self.find_nearest_rack_from_point_STR_bbox(self._tol_connect, pos)
onpoints[name] = (onpoint, rackname)
except LookupError:
errors.append((name, pos))
continue
onpoints[name] = (onpoint, rackname)
self.add_point_to_rack(onpoint, rackname)
virtual_rackname = f"v-{name}-{rackname}"
@@ -487,76 +440,6 @@ class Anlage():
return errors
def connect_equipment_batch(self, equipment:dict, onpoints:dict) -> list:
if not hasattr(self, "_rack_tree"):
self._build_rack_strtree()
devices = list(equipment.items())
device_names = [name for name, _ in devices]
device_points = [pos for _, pos in devices]
idx_rack, distances = self._rack_tree.query_nearest(device_points, return_distance=True, all_matches=False)
# !!! Problem !!!: query gibt mehrere Ergebnisse zurück -> kann dann nicht zugeordnet werden
# Greifen des ersten ergebnisses nicht zielführend, da nicht das näheste
errors = []
for i, (rack_idxs, dist) in enumerate(zip(idx_rack, distances)):
# Nehme ersten Treffer
rack_idx = int(rack_idxs[0])
dist = float(dist)
if dist > self._tol_connect:
errors.append(devices[i])
continue
eqname, eqpos = devices[i]
nearest_line = self._rack_lines[rack_idx]
rackname = self._rack_map[nearest_line]
onpoint = nearest_line.interpolate(nearest_line.project(eqpos))
onpoints[eqname] = (onpoint, rackname)
self.add_point_to_rack(onpoint, rackname)
virtual_rackname = f"v-{eqname}-{rackname}"
self._racks.add_rack(eqpos, onpoint, virtual_rackname)
return errors
def find_nearest_rack_from_point(self, max_dist, coarse_step, sensor:Point, racks:dict) -> tuple[Point, str]:
# 1. grobe Kandidatensuche
candidate_lines = []
radius = coarse_step
rack_lines = dict()
while radius <= max_dist:
circle = sensor.buffer(radius)
for r_name, pts in racks.items():
line = LineString([pts[0], pts[-1]]) #Linestring aus erstem und letzten Eintrag in Rack dict erzeugen
if circle.intersects(line):
candidate_lines.append((r_name, line))
if candidate_lines:
break
radius += coarse_step
if not candidate_lines:
return None, None
# 2. Feinbestimmung über Distanz
candidates_distance = [
(r_name, line, line.distance(sensor))
for r_name, line in candidate_lines
]
# Sortieren nach Abstand
candidates_distance.sort(key=lambda x: x[2])
'''# Theoretisch könnten mehrere ähnlich naheliegende Racks zurückgegeben werden.'''
r_best, line_best, _ = candidates_distance[0] # Hier wird nur das tatsächlich dem Senso nächste Rack gegriffen
# Aufpunkt bestimmen
nearest_point = line_best.interpolate(line_best.project(sensor))
return (nearest_point, r_best)
def search_connections(self, rack_segments, segment_endpoints, tol, tol_step):
''' Aus Rack Segmenten und Endpunkten der Racks wird unter Berücksichtigung von Toleranz naheliegende Endpunkte gefunden.
Zuerst echte Schnittpunkte und im Anschluss via Kreissuche neheliegende Punkte und deren gepinnte Berührpunkte
@@ -736,132 +619,122 @@ class Anlage():
def show_node_ids(self):
return self._nodeids.show()
class TestLinesweep(unittest.TestCase):
class TestPlant(unittest.TestCase):
# def test_duplicate_points(self):
# ''' Testet das Nicht-Hinzufügen von doppelten Punkten'''
# # Initialisiere die Liste an Knoten
# nodeids = NodeIDs()
def test_duplicate_points(self):
''' Testet das Nicht-Hinzufügen von doppelten Punkten'''
# Initialisiere die Liste an Knoten
nodeids = NodeIDs()
# # Setze gleichen Knoten doppelt
# nodeids.add_point(Point(1,1))
# nodeids.add_point(Point(1,1))
# Setze gleichen Knoten doppelt
nodeids.add_point(Point(1,1))
nodeids.add_point(Point(1,1))
# self.assertEqual(nodeids.size_of(), 1)
self.assertEqual(nodeids.size_of(), 1)
# def test_cut_rack_in_segments(self):
# ''' Teilt Rack aus Polyline in mehrere Segmente automatisch auf.'''
# racks_data = {
# 'Rack_1': [Point(0, 0), Point(0, 10), Point (10, 10)],
# 'Rack_2': [Point(-5, 5), Point(5, 5)]
# }
def test_cut_rack_in_segments(self):
''' Teilt Rack aus Polyline in mehrere Segmente automatisch auf.'''
racks_data = {
'Rack_1': [Point(0, 0), Point(0, 10), Point (10, 10)],
'Rack_2': [Point(-5, 5), Point(5, 5)]
}
# # Initialisiere Racks
# rack = RackIDs()
# # Füge Racks aus gegebenen Daten hinzu und teile Rack_1 bestehend aus 3 Punkten in 2 Racks auf
# rack.add_racks(racks_data)
# Initialisiere Racks
rack = RackIDs()
# Füge Racks aus gegebenen Daten hinzu und teile Rack_1 bestehend aus 3 Punkten in 2 Racks auf
rack.add_racks(racks_data)
# self.assertEqual(rack.get_rack_names(), ['Rack_1-1', 'Rack_1-2', 'Rack_2'])
self.assertEqual(rack.get_rack_names(), ['Rack_1-1', 'Rack_1-2', 'Rack_2'])
# def test_intersect_segments(self):
# ''' Stellt Schnittpunkte zwischen Racks fest und fügt Schnittpunkt zu Rack hinzu. '''
def test_intersect_segments(self):
''' Stellt Schnittpunkte zwischen Racks fest und fügt Schnittpunkt zu Rack hinzu. '''
# racks_data = {
# 'Rack_1': [Point(0, 0), Point(0, 10), Point (10, 10)],
# 'Rack_2': [Point(-5, 5), Point(5, 5)],
# }
racks_data = {
'Rack_1': [Point(0, 0), Point(0, 10), Point (10, 10)],
'Rack_2': [Point(-5, 5), Point(5, 5)],
}
# # Initialisiere Racks
# rack = RackIDs()
# # Füge Racks aus gegebenen Daten hinzu und teile Rack_1 bestehend aus 3 Punkten in 2 Racks auf
# rack.add_racks(racks_data)
# # Verknüpfe Racks mit echten Schnittpunkten und füge Schnittpunkte (exakt & beinahe) zu jeweiligem Rack hinzu
# rack.join_racks()
# Initialisiere Racks
rack = RackIDs()
# Füge Racks aus gegebenen Daten hinzu und teile Rack_1 bestehend aus 3 Punkten in 2 Racks auf
rack.add_racks(racks_data)
# Verknüpfe Racks mit echten Schnittpunkten und füge Schnittpunkte (exakt & beinahe) zu jeweiligem Rack hinzu
rack.join_racks()
# self.assertEqual(rack.get_points_from_rack("Rack_1-1"), [Point(0, 0), Point(0, 5), Point (0, 10)])
self.assertEqual(rack.get_points_from_rack("Rack_1-1"), [Point(0, 0), Point(0, 5), Point (0, 10)])
# def test_snap_segments(self):
# ''' Verlängert Anfangs und Endpunkte von Racks, sodass sie auf naheliegenden Racks liegen'''
# racks_data = {
# 'Rack_1': [Point(0, 0), Point(0, 10)],
# 'Rack_2': [Point(1, 5), Point(5, 5)],
# 'Rack_3': [Point(1.5, 7.5), Point(5, 7.5)]
# }
def test_snap_segments(self):
''' Verlängert Anfangs und Endpunkte von Racks, sodass sie auf naheliegenden Racks liegen'''
racks_data = {
'Rack_1': [Point(0, 0), Point(0, 10)],
'Rack_2': [Point(1, 5), Point(5, 5)],
'Rack_3': [Point(1.5, 7.5), Point(5, 7.5)]
}
# # Initialisiere Racks
# rack = RackIDs(tol_snap=1)
# # Füge Racks aus gegebenen Daten hinzu und teile Rack_1 bestehend aus 3 Punkten in 2 Racks auf
# rack.add_racks(racks_data)
# # Verknüpfe Racks mit echten Schnittpunkten und füge Schnittpunkte (exakt & beinahe) zu jeweiligem Rack hinzu
# rack.join_racks()
# Initialisiere Racks
rack = RackIDs(tol_snap=1)
# Füge Racks aus gegebenen Daten hinzu und teile Rack_1 bestehend aus 3 Punkten in 2 Racks auf
rack.add_racks(racks_data)
# Verknüpfe Racks mit echten Schnittpunkten und füge Schnittpunkte (exakt & beinahe) zu jeweiligem Rack hinzu
rack.join_racks()
# #Rack 2 wird verlängert auf SP mit Rack 1. Rack 3 ausserhalb der Toleranz
# self.assertEqual(rack.get_points_from_rack("Rack_1"), [Point(0, 0), Point(0, 5), Point (0, 10)])
#Rack 2 wird verlängert auf SP mit Rack 1. Rack 3 ausserhalb der Toleranz
self.assertEqual(rack.get_points_from_rack("Rack_1"), [Point(0, 0), Point(0, 5), Point (0, 10)])
# def test_ids_to_point(self):
# ''' Testet, ob gefragter Punkt auf Racks a, b, c liegt'''
def test_ids_to_point(self):
''' Testet, ob gefragter Punkt auf Racks a, b, c liegt'''
# res_rack_seg = {'Rack_1-0': [Point(1, 0), Point(5, 6)],
# 'Rack_2-0': [Point(1, 8), Point(1, 0)],
# 'Rack_2-1': [Point(0, 10), Point(5, 10)]}
res_rack_seg = {'Rack_1-0': [Point(1, 0), Point(5, 6)],
'Rack_2-0': [Point(1, 8), Point(1, 0)],
'Rack_2-1': [Point(0, 10), Point(5, 10)]}
# point2rack = RackIDs()
# point2rack.add_racks(res_rack_seg)
point2rack = RackIDs()
point2rack.add_racks(res_rack_seg)
# self.assertEqual(point2rack.get_racks_from_point(Point(1, 0)), ["Rack_1-0", "Rack_2-0"])
# self.assertEqual(point2rack.get_racks_from_point(Point(5, 6)), ["Rack_1-0"])
# self.assertEqual(point2rack.get_points_from_rack("Rack_2-0"), [Point(1, 0), Point(1, 8)])
# def test_add_point_interim(self):
# ''' Testet das hinzufügen und einsortieren eines Zwischenpunktes zwischen Rack-Anfang und Rack-Ende'''
self.assertEqual(point2rack.get_racks_from_point(Point(1, 0)), ["Rack_1-0", "Rack_2-0"])
self.assertEqual(point2rack.get_racks_from_point(Point(5, 6)), ["Rack_1-0"])
self.assertEqual(point2rack.get_points_from_rack("Rack_2-0"), [Point(1, 0), Point(1, 8)])
def test_add_point_interim(self):
''' Testet das hinzufügen und einsortieren eines Zwischenpunktes zwischen Rack-Anfang und Rack-Ende'''
# res_rack_seg = {'Rack_1-0': [Point(1, 0), Point(5, 6)],
# 'Rack_2-0': [Point(1, 8), Point(1, 0)],
# 'Rack_2-1': [Point(0, 10), Point(5, 10)]}
res_rack_seg = {'Rack_1-0': [Point(1, 0), Point(5, 6)],
'Rack_2-0': [Point(1, 8), Point(1, 0)],
'Rack_2-1': [Point(0, 10), Point(5, 10)]}
# point2rack = RackIDs()
# point2rack.add_racks(res_rack_seg)
# point2rack.add_point_to_rack(Point(1,4), "Rack_2-0")
point2rack = RackIDs()
point2rack.add_racks(res_rack_seg)
point2rack.add_point_to_rack(Point(1,4), "Rack_2-0")
# self.assertEqual(point2rack.get_points_from_rack("Rack_2-0"), [Point(1, 0), Point(1,4), Point(1, 8)])
self.assertEqual(point2rack.get_points_from_rack("Rack_2-0"), [Point(1, 0), Point(1,4), Point(1, 8)])
def test_add_sensor(self):
''' Erzeugt Aufpunkt an dem Sensor nähesten Rack und fügt diesen auf Rack ein (sortiert).'''
# def test_add_sensor(self):
# ''' Erzeugt Aufpunkt an dem Sensor nähesten Rack und fügt diesen auf Rack ein (sortiert).'''
# rack_segs = {'Rack_1-0': [Point(0, 0), Point(0, 10)],
# 'Rack_2-0': [Point(10, -2), Point(10, 5)],
# 'Rack_2-1': [Point(0, 3), Point(10, 3)]}
rack_segs = {'Rack_1-0': [Point(0, 0), Point(0, 10)],
'Rack_2-0': [Point(10, -2), Point(10, 5)],
'Rack_2-1': [Point(0, 3), Point(10, 3)]}
# sensors = {'Sens_1': Point(1, 1),
# 'Sens_2': Point(2, 4),
# 'Sens_3': Point(9, 2)}
sensors = {'Sens_1': Point(1, 1),
'Sens_2': Point(2, 4),
'Sens_3': Point(9, 2)}
# an = Anlage()
# point2rack = an.set_racks(rack_segs)
# an.add_sensors(sensors)
an = Anlage()
point2rack = an.set_racks(rack_segs)
an.add_sensors(sensors)
# plist1 = an.get_points_from_rack("Rack_1-0")
plist1 = an.get_points_from_rack("Rack_1-0")
# an.connect_sensors_to_racks()
# plist2 = an.get_points_from_rack("Rack_1-0")
an.connect_sensors_to_racks()
plist2 = an.get_points_from_rack("Rack_1-0")
# self.assertEqual(plist1, [Point(0, 0), Point(0, 10)])
# self.assertEqual(plist2, [Point(0, 0), Point(0,1), Point(0, 10)])
self.assertEqual(plist1, [Point(0, 0), Point(0, 10)])
self.assertEqual(plist2, [Point(0, 0), Point(0,1), Point(0, 10)])
def test_add_equipment_w_tree(self):
@@ -876,7 +749,7 @@ class TestLinesweep(unittest.TestCase):
distributors = {'Dist_1': Point(-1, 9),
'Dist_2': Point(11, 0)}
an = Anlage(tol_snap=1.5)
an = Anlage(tol_snap=1.5, tol_connect=1.5)
an.set_racks(racks)
an.join_racks()
@@ -891,193 +764,191 @@ class TestLinesweep(unittest.TestCase):
self.assertEqual(plist1, [Point(0, 0), Point(0, 1), Point(0, 3), Point(0, 9), Point(0, 10)])
self.assertEqual(plist2, [Point(10, -2), Point(10, 0), Point(10, 2), Point(10, 3), Point(10, 5)])
def test_wegsuche_str_tree(self):
# Beispiel-Daten
points = [Point(x, y) for x, y in [(1, 2), (3, 4), (5, 5), (7, 8)]]
lines = [LineString([(0, 1), (2, 3)]), LineString([(4, 4), (6, 6)]), LineString([(8, 8), (10, 10)])]
# STRtree erstellen mit tatsächlichen LineStrings
tree = STRtree(lines)
# def test_add_equipment_w_tree_batch(self):
# Zuordnung
nearest_line_for_point = {}
for point in points:
candidates = tree.query(point) # Gibt direkt LineStrings zurück
if not candidates:
continue
candidates = [lines[idx] for idx in candidates]
nearest_line = min(candidates, key=lambda line: line.distance(point))
nearest_line_for_point[point] = nearest_line
# Ausgabe
for point, line in nearest_line_for_point.items():
print(f"Punkt {point} liegt am nächsten zu Linie {line}")
def test_wegsuche_w_tree(self):
racks = {'Rack_1-0': [Point(0, 0), Point(0, 10)],
'Rack_2-0': [Point(10, -2), Point(10, 5)],
'Rack_2-1': [Point(0, 3), Point(10, 3)]}
# racks = {'Rack_1': [Point(0, 0), Point(0, 10)],
# 'Rack_2': [Point(10, -2), Point(10, 5)],
# 'Rack_3': [Point(0, 3), Point(10, 3)]}
sensors = {'Sens_1': Point(1, 1),
'Sens_2': Point(2, 4),
'Sens_3': Point(9, 2)}
# sensors = {'Sens_1': Point(1, 1),
# 'Sens_2': Point(2, 4),
# 'Sens_3': Point(9, 2)}
distributors = {'Dist_1': Point(-1, 9),
'Dist_2': Point(11, 0)}
# distributors = {'Dist_1': Point(-1, 9),
# 'Dist_2': Point(11, 0)}
mapping = {'Dist_1': ['Sens_1', 'Sens_2'],
'Dist_2': ['Sens_3']}
# an = Anlage(tol_snap=1)
# an.set_racks(racks)
# an.join_racks()
an = Anlage(tol_snap=1)
an.set_racks(racks)
an.join_racks()
# an.add_sensors(sensors)
# an.add_distributors(distributors)
# an.connect_equipment_batch(an._sensors, an._sensor_onpoints)
# an.connect_equipment_batch(an._distributors, an._distributors_onpoints)
an.add_sensors(sensors)
an.add_distributors(distributors)
an.connect_equipment_to_racks(an._sensors, an._sensor_onpoints)
an.connect_equipment_to_racks(an._distributors, an._distributors_onpoints)
# plist1 = an.get_points_from_rack("Rack_1")
# plist2 = an.get_points_from_rack("Rack_2")
an.map_distributors_to_sensors(mapping)
# G1 = nx.Graph()
# pos = an.generate_graph(G1)
# nx.draw(G1, pos, with_labels=False, node_size=10, font_size=8)
# plt.show()
G = nx.Graph()
#Fülle eben erstellten Graphen mit Daten
pos = an.generate_graph(G)
#Extrahiere Farb-Informationen der Kanten
edge_colors = [G[u][v].get('color', 'black') for u, v in G.edges()]
#Zeiche Graphen und zeige in
nx.draw(G, pos, with_labels=False, node_size=10, font_size=8, edge_color=edge_colors)
plt.show()
#Ermittle kürzeste Wege von Unterverteilern zu zugehörigen Sensoren
paths = an.create_cable_paths(G)
paths_by_id = {p['id']: p for p in paths["kabel"]}
# self.assertEqual(plist1, [Point(0, 0), Point(0, 1), Point(0, 3), Point(0, 9), Point(0, 10)])
# self.assertEqual(plist2, [Point(10, -2), Point(10, 0), Point(10, 2), Point(10, 3), Point(10, 5)])
self.assertEqual(paths_by_id['Dist_1-Sens_1']["coords"], [{'x': -1.0, 'y': 9.0}, {'x': 0.0, 'y': 9.0}, {'x': 0.0, 'y': 3.0}, {'x': 0.0, 'y': 1.0}, {'x': 1.0, 'y': 1.0}])
self.assertEqual(paths_by_id['Dist_1-Sens_2']["coords"], [{'x': -1.0, 'y': 9.0}, {'x': 0.0, 'y': 9.0}, {'x': 0.0, 'y': 3.0}, {'x': 2.0, 'y': 3.0}, {'x': 2.0, 'y': 4.0}])
self.assertEqual(paths_by_id['Dist_2-Sens_3']["coords"], [{'x': 11.0, 'y': 0.0}, {'x': 10.0, 'y': 0.0}, {'x': 10.0, 'y': 2.0}, {'x': 9.0, 'y': 2.0}])
self.assertEqual(paths_by_id['Dist_1-Sens_1']["length"], 10)
self.assertEqual(paths_by_id['Dist_1-Sens_2']["length"], 10)
self.assertEqual(paths_by_id['Dist_2-Sens_3']["length"], 4)
# def test_wegsuche_w_tree(self):
# racks = {'Rack_1-0': [Point(0, 0), Point(0, 10)],
# 'Rack_2-0': [Point(10, -2), Point(10, 5)],
# 'Rack_2-1': [Point(0, 3), Point(10, 3)]}
def test_generate_graph(self):
'''Generiert einen Graphen in 3 unterschiedlichen Ausbaustufen (nur Racks, Racks+Sensoren, Racks+Sensoren+Unterverteiler)'''
# sensors = {'Sens_1': Point(1, 1),
# 'Sens_2': Point(2, 4),
# 'Sens_3': Point(9, 2)}
rack_segs = {'Rack_1-0': [Point(0, 0), Point(0, 10)],
'Rack_2-0': [Point(10, -2), Point(10, 5)],
'Rack_2-1': [Point(0, 3), Point(10, 3)]}
# distributors = {'Dist_1': Point(-1, 9),
# 'Dist_2': Point(11, 0)}
sensors = {'Sens_1': Point(1, 1),
'Sens_2': Point(2, 4),
'Sens_3': Point(9, 2)}
# mapping = {'Dist_1': ['Sens_1', 'Sens_2'],
# 'Dist_2': ['Sens_3']}
distributors = {'Dist_1': Point(-1, 9),
'Dist_2': Point(11, 0)}
an = Anlage()
an.set_racks(rack_segs)
an.join_racks
G1 = nx.Graph()
pos = an.generate_graph(G1)
nx.draw(G1, pos, with_labels=False, node_size=10, font_size=8)
plt.show()
an.add_sensors(sensors)
an.connect_sensors_to_racks()
G2 = nx.Graph()
pos = an.generate_graph(G2)
edge_colors = [G2[u][v].get('color', 'black') for u, v in G2.edges()]
nx.draw(G2, pos, with_labels=False, node_size=10, font_size=8, edge_color=edge_colors)
plt.show()
an.add_distributors(distributors)
an.connect_distributor_to_racks()
G3 = nx.Graph()
pos = an.generate_graph(G3)
edge_colors = [G3[u][v].get('color', 'black') for u, v in G3.edges()]
nx.draw(G3, pos, with_labels=False, node_size=10, font_size=8, edge_color=edge_colors)
plt.show()
def test_Wegsuche(self):
''' Erstellt Graphen mit Racks, Sensoren und Unterverteilern und sucht kürzeste Wege von Unterverteiler zu zugehörigen Sensoren'''
# an = Anlage(tol_snap=1)
# an.set_racks(racks)
# an.join_racks()
# an.add_sensors(sensors)
# an.add_distributors(distributors)
# an.connect_equipment_to_racks(an._sensors, an._sensor_onpoints)
# an.connect_equipment_to_racks(an._distributors, an._distributors_onpoints)
# an.map_distributors_to_sensors(mapping)
# G = nx.Graph()
# Fülle eben erstellten Graphen mit Daten
# pos = an.generate_graph(G)
# Extrahiere Farb-Informationen der Kanten
# edge_colors = [G[u][v].get('color', 'black') for u, v in G.edges()]
# Zeiche Graphen und zeige in
# nx.draw(G, pos, with_labels=False, node_size=10, font_size=8, edge_color=edge_colors)
# plt.show()
# Ermittle kürzeste Wege von Unterverteilern zu zugehörigen Sensoren
# paths = an.create_cable_paths(G)
# paths_by_id = {p['id']: p for p in paths["kabel"]}
# self.assertEqual(paths_by_id['Dist_1-Sens_1']["coords"], [{'x': -1.0, 'y': 9.0}, {'x': 0.0, 'y': 9.0}, {'x': 0.0, 'y': 3.0}, {'x': 0.0, 'y': 1.0}, {'x': 1.0, 'y': 1.0}])
# self.assertEqual(paths_by_id['Dist_1-Sens_2']["coords"], [{'x': -1.0, 'y': 9.0}, {'x': 0.0, 'y': 9.0}, {'x': 0.0, 'y': 3.0}, {'x': 2.0, 'y': 3.0}, {'x': 2.0, 'y': 4.0}])
# self.assertEqual(paths_by_id['Dist_2-Sens_3']["coords"], [{'x': 11.0, 'y': 0.0}, {'x': 10.0, 'y': 0.0}, {'x': 10.0, 'y': 2.0}, {'x': 9.0, 'y': 2.0}])
# self.assertEqual(paths_by_id['Dist_1-Sens_1']["length"], 10)
# self.assertEqual(paths_by_id['Dist_1-Sens_2']["length"], 10)
# self.assertEqual(paths_by_id['Dist_2-Sens_3']["length"], 4)
# def test_generate_graph(self):
# '''Generiert einen Graphen in 3 unterschiedlichen Ausbaustufen (nur Racks, Racks+Sensoren, Racks+Sensoren+Unterverteiler)'''
rack_segs = {'Rack_1': [Point(0, 0), Point(0, 10)],
'Rack_2': [Point(10, -2), Point(10, 5)],
'Rack_3': [Point(0, 3), Point(10, 3)]}
# rack_segs = {'Rack_1-0': [Point(0, 0), Point(0, 10)],
# 'Rack_2-0': [Point(10, -2), Point(10, 5)],
# 'Rack_2-1': [Point(0, 3), Point(10, 3)]}
sensors = {'Sens_1': Point(1, 1),
'Sens_2': Point(2, 4),
'Sens_3': Point(9, 2)}
# sensors = {'Sens_1': Point(1, 1),
# 'Sens_2': Point(2, 4),
# 'Sens_3': Point(9, 2)}
distributors = {'Dist_1': Point(-1, 9),
'Dist_2': Point(11, 0)}
# distributors = {'Dist_1': Point(-1, 9),
# 'Dist_2': Point(11, 0)}
mapping = {'Dist_1': ['Sens_1', 'Sens_2'],
'Dist_2': ['Sens_3']}
# an = Anlage()
# an.set_racks(rack_segs)
# an.join_racks
# G1 = nx.Graph()
# pos = an.generate_graph(G1)
# nx.draw(G1, pos, with_labels=False, node_size=10, font_size=8)
# plt.show()
# an.add_sensors(sensors)
# an.connect_sensors_to_racks()
# G2 = nx.Graph()
# pos = an.generate_graph(G2)
# edge_colors = [G2[u][v].get('color', 'black') for u, v in G2.edges()]
# nx.draw(G2, pos, with_labels=False, node_size=10, font_size=8, edge_color=edge_colors)
# plt.show()
# an.add_distributors(distributors)
# an.connect_distributor_to_racks()
# G3 = nx.Graph()
# pos = an.generate_graph(G3)
# edge_colors = [G3[u][v].get('color', 'black') for u, v in G3.edges()]
# nx.draw(G3, pos, with_labels=False, node_size=10, font_size=8, edge_color=edge_colors)
# plt.show()
#Erstelle Anlage
an = Anlage(tol_snap=1)
#Füge racks aus Daten hinzu
an.set_racks(rack_segs)
#Verbinde Racks miteinander (ggf. verlängere ungenaue Racks)
an.join_racks()
#Füge Sensoren als Knoten hinzu
an.add_sensors(sensors)
#Verbinde Sensoren mit deren naheliegendsten Racks
an.connect_sensors_to_racks()
#Füge UV hinzu
an.add_distributors(distributors)
#Verbinde UV mit deren naheliegendsten Racks
an.connect_distributor_to_racks()
#Verknüpfe Sensoren mit zugehörigem UV
an.map_distributors_to_sensors(mapping)
#Initialisiere Graph
G3 = nx.Graph()
#Fülle eben erstellten Graphen mit Daten
pos = an.generate_graph(G3)
#Extrahiere Farb-Informationen der Kanten
edge_colors = [G3[u][v].get('color', 'black') for u, v in G3.edges()]
#Zeiche Graphen und zeige in
nx.draw(G3, pos, with_labels=False, node_size=10, font_size=8, edge_color=edge_colors)
plt.show()
# def test_Wegsuche(self):
# ''' Erstellt Graphen mit Racks, Sensoren und Unterverteilern und sucht kürzeste Wege von Unterverteiler zu zugehörigen Sensoren'''
# rack_segs = {'Rack_1': [Point(0, 0), Point(0, 10)],
# 'Rack_2': [Point(10, -2), Point(10, 5)],
# 'Rack_3': [Point(0, 3), Point(10, 3)]}
# sensors = {'Sens_1': Point(1, 1),
# 'Sens_2': Point(2, 4),
# 'Sens_3': Point(9, 2)}
# distributors = {'Dist_1': Point(-1, 9),
# 'Dist_2': Point(11, 0)}
# mapping = {'Dist_1': ['Sens_1', 'Sens_2'],
# 'Dist_2': ['Sens_3']}
#Ermittle kürzeste Wege von Unterverteilern zu zugehörigen Sensoren
paths = an.create_cable_paths(G3)
# Erstelle Anlage
# an = Anlage(tol_snap=1)
# Füge racks aus Daten hinzu
# an.set_racks(rack_segs)
# Verbinde Racks miteinander (ggf. verlängere ungenaue Racks)
# an.join_racks()
# Füge Sensoren als Knoten hinzu
# an.add_sensors(sensors)
# Verbinde Sensoren mit deren naheliegendsten Racks
# an.connect_sensors_to_racks()
# Füge UV hinzu
# an.add_distributors(distributors)
# Verbinde UV mit deren naheliegendsten Racks
# an.connect_distributor_to_racks()
# Verknüpfe Sensoren mit zugehörigem UV
# an.map_distributors_to_sensors(mapping)
# Initialisiere Graph
# G3 = nx.Graph()
# Fülle eben erstellten Graphen mit Daten
# pos = an.generate_graph(G3)
# Extrahiere Farb-Informationen der Kanten
# edge_colors = [G3[u][v].get('color', 'black') for u, v in G3.edges()]
# Zeiche Graphen und zeige in
# nx.draw(G3, pos, with_labels=False, node_size=10, font_size=8, edge_color=edge_colors)
# plt.show()
# Ermittle kürzeste Wege von Unterverteilern zu zugehörigen Sensoren
# paths = an.create_cable_paths(G3)
# paths_by_id = {p['id']: p for p in paths["kabel"]}
paths_by_id = {p['id']: p for p in paths["kabel"]}
# self.assertEqual(paths_by_id['Dist_1-Sens_1']["coords"], [{'x': -1.0, 'y': 9.0}, {'x': 0.0, 'y': 9.0}, {'x': 0.0, 'y': 3.0}, {'x': 0.0, 'y': 1.0}, {'x': 1.0, 'y': 1.0}])
# self.assertEqual(paths_by_id['Dist_1-Sens_2']["coords"], [{'x': -1.0, 'y': 9.0}, {'x': 0.0, 'y': 9.0}, {'x': 0.0, 'y': 3.0}, {'x': 2.0, 'y': 3.0}, {'x': 2.0, 'y': 4.0}])
# self.assertEqual(paths_by_id['Dist_2-Sens_3']["coords"], [{'x': 11.0, 'y': 0.0}, {'x': 10.0, 'y': 0.0}, {'x': 10.0, 'y': 2.0}, {'x': 9.0, 'y': 2.0}])
# self.assertEqual(paths_by_id['Dist_1-Sens_1']["length"], 10)
# self.assertEqual(paths_by_id['Dist_1-Sens_2']["length"], 10)
# self.assertEqual(paths_by_id['Dist_2-Sens_3']["length"], 4)
self.assertEqual(paths_by_id['Dist_1-Sens_1']["coords"], [{'x': -1.0, 'y': 9.0}, {'x': 0.0, 'y': 9.0}, {'x': 0.0, 'y': 3.0}, {'x': 0.0, 'y': 1.0}, {'x': 1.0, 'y': 1.0}])
self.assertEqual(paths_by_id['Dist_1-Sens_2']["coords"], [{'x': -1.0, 'y': 9.0}, {'x': 0.0, 'y': 9.0}, {'x': 0.0, 'y': 3.0}, {'x': 2.0, 'y': 3.0}, {'x': 2.0, 'y': 4.0}])
self.assertEqual(paths_by_id['Dist_2-Sens_3']["coords"], [{'x': 11.0, 'y': 0.0}, {'x': 10.0, 'y': 0.0}, {'x': 10.0, 'y': 2.0}, {'x': 9.0, 'y': 2.0}])
self.assertEqual(paths_by_id['Dist_1-Sens_1']["length"], 10)
self.assertEqual(paths_by_id['Dist_1-Sens_2']["length"], 10)
self.assertEqual(paths_by_id['Dist_2-Sens_3']["length"], 4)
if __name__ == '__main__':
unittest.main()
suite = unittest.TestSuite()
suite.addTest(TestPlant('test_duplicate_points'))
suite.addTest(TestPlant('test_cut_rack_in_segments'))
suite.addTest(TestPlant('test_intersect_segments'))
suite.addTest(TestPlant('test_snap_segments'))
suite.addTest(TestPlant('test_ids_to_point'))
suite.addTest(TestPlant('test_add_point_interim'))
suite.addTest(TestPlant('test_add_sensor'))
suite.addTest(TestPlant('test_add_equipment_w_tree'))
suite.addTest(TestPlant('test_add_equipment_w_tree_batch'))
suite.addTest(TestPlant('test_wegsuche_str_tree'))
suite.addTest(TestPlant('test_wegsuche_w_tree'))
suite.addTest(TestPlant('test_generate_graph'))
suite.addTest(TestPlant('test_Wegsuche'))
runner = unittest.TextTestRunner()
runner.run(suite)
#unittest.main()
-3
View File
@@ -20,9 +20,6 @@ pip-tools==7.4.1
PyMuPDF==1.25.5
pyparsing==3.2.3
pyproject_hooks==1.2.0
PySide6==6.9.0
PySide6_Addons==6.9.0
PySide6_Essentials==6.9.0
python-dateutil==2.8.2
pytz==2023.3.post1
setuptools==80.0.0