Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 23de34503d | |||
| 9370ef881a | |||
| ef1e78de2e |
+15
-11
@@ -33,7 +33,7 @@ def merge_two_dicts(x, y):
|
|||||||
return z
|
return z
|
||||||
|
|
||||||
def get_input_positions(msp: ezdxf.document.Drawing.modelspace):
|
def get_input_positions(msp: ezdxf.document.Drawing.modelspace):
|
||||||
"""hole alle Positionen der Eingänge
|
"""hole alle Positionen der Eingänge !!Sensor Positionen erst nach Offsett-Addition "Mitte-Mitte"!!
|
||||||
"""
|
"""
|
||||||
allIds = dict()
|
allIds = dict()
|
||||||
SpecialKeys = ["MB", # Separator
|
SpecialKeys = ["MB", # Separator
|
||||||
@@ -71,7 +71,7 @@ def get_input_positions(msp: ezdxf.document.Drawing.modelspace):
|
|||||||
pos_midx = pos.x + breite_marker*0.5
|
pos_midx = pos.x + breite_marker*0.5
|
||||||
pos_midy = pos.y + hoehe_marker*0.5
|
pos_midy = pos.y + hoehe_marker*0.5
|
||||||
|
|
||||||
ld["pos"] = (pos_midx, pos_midy)
|
ld["pos"] = (round(pos_midx, 1), round(pos_midy, 1))
|
||||||
|
|
||||||
# Nur wenn eine ID vorhanden ist, und eine gültige Position existiert
|
# Nur wenn eine ID vorhanden ist, und eine gültige Position existiert
|
||||||
if id and "pos" in ld and isinstance(ld["pos"], tuple) and len(ld["pos"]) == 2:
|
if id and "pos" in ld and isinstance(ld["pos"], tuple) and len(ld["pos"]) == 2:
|
||||||
@@ -83,7 +83,7 @@ def get_input_positions(msp: ezdxf.document.Drawing.modelspace):
|
|||||||
|
|
||||||
|
|
||||||
def get_subdistributor_positions(msp):
|
def get_subdistributor_positions(msp):
|
||||||
"""hole alle Positionen der Unterverteiler
|
"""hole alle Positionen der Unterverteiler !!UV-Positionen bereits "Mitte-Mitte"!!
|
||||||
"""
|
"""
|
||||||
# # Über alle Texte laufen
|
# # Über alle Texte laufen
|
||||||
# for text in msp.query('MTEXT'):
|
# for text in msp.query('MTEXT'):
|
||||||
@@ -106,7 +106,7 @@ def get_subdistributor_positions(msp):
|
|||||||
match = re.search(r"UC\w+", text.dxf.text)
|
match = re.search(r"UC\w+", text.dxf.text)
|
||||||
if match:
|
if match:
|
||||||
nameUC = match.group(0)
|
nameUC = match.group(0)
|
||||||
ret[nameUC] = text.dxf.insert
|
ret[nameUC] = (round(text.dxf.insert[0],1), round(text.dxf.insert[1],1)) #nur x und y Koordinate in Json schreiben
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
@@ -125,17 +125,21 @@ def print_polyline(e):
|
|||||||
print("Diese Polyline ist geschlossen.")
|
print("Diese Polyline ist geschlossen.")
|
||||||
|
|
||||||
def get_rack_positions(msp):
|
def get_rack_positions(msp):
|
||||||
"""hole alle Positionen aller Kabelpritschen
|
"""hole alle Positionen aller Kabelpritschen und nummeriere Racks"""
|
||||||
"""
|
ret = dict()
|
||||||
|
rack_counter = 1 #Zaehler für Rack Nummerierung
|
||||||
|
|
||||||
ret = list()
|
|
||||||
for e in msp.query('LWPOLYLINE[layer=="PRITSCHE_200-60"]'):
|
for e in msp.query('LWPOLYLINE[layer=="PRITSCHE_200-60"]'):
|
||||||
#print_polyline(e)
|
#print_polyline(e)
|
||||||
poly = list()
|
rack_key = f"Rack_{rack_counter}"
|
||||||
|
ret[rack_key] = dict()
|
||||||
|
|
||||||
|
node_counter = 1
|
||||||
for x, y, start_width, end_width, bulge in e.get_points(): # Gibt Tuple (x, y, start_width, end_width, bulge)
|
for x, y, start_width, end_width, bulge in e.get_points(): # Gibt Tuple (x, y, start_width, end_width, bulge)
|
||||||
point = (x,y)
|
node_key = f"Node_{node_counter}"
|
||||||
poly.append(point)
|
ret[rack_key][node_key] = [round(x,1), round(y,1)]
|
||||||
ret.append(poly)
|
node_counter +=1
|
||||||
|
rack_counter +=1
|
||||||
# iterate over all entities in modelspace
|
# iterate over all entities in modelspace
|
||||||
# for e in msp:
|
# for e in msp:
|
||||||
# if e.dxftype() == "LINE":
|
# if e.dxftype() == "LINE":
|
||||||
|
|||||||
+96
-17
@@ -3,6 +3,8 @@ import json
|
|||||||
import argparse
|
import argparse
|
||||||
import heapq
|
import heapq
|
||||||
import math
|
import math
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import networkx as nx
|
||||||
|
|
||||||
# Hilfsfunktionen
|
# Hilfsfunktionen
|
||||||
def load_json(filepath):
|
def load_json(filepath):
|
||||||
@@ -12,25 +14,29 @@ def load_json(filepath):
|
|||||||
def parse_pos(pos_str):
|
def parse_pos(pos_str):
|
||||||
""" Konvertiert '(x, y)' oder '(x, y, z)' in ein Tuple """
|
""" Konvertiert '(x, y)' oder '(x, y, z)' in ein Tuple """
|
||||||
try:
|
try:
|
||||||
return tuple(map(float, pos_str.strip('()').split(',')))
|
return tuple(map(float, pos_str.strip('[]').split(',')))
|
||||||
except Exception:
|
except Exception:
|
||||||
raise ValueError(f"Ungültiges Positionsformat: {pos_str}")
|
raise ValueError(f"Ungültiges Positionsformat: {pos_str}")
|
||||||
|
|
||||||
def distance(p1, p2):
|
def distance(p1, p2):
|
||||||
""" Euklidische Distanz in 2D """
|
""" Euklidische Distanz in 2D """
|
||||||
return math.sqrt((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2)
|
return math.sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)
|
||||||
|
|
||||||
def add_edge(graph, node1, node2, dist):
|
def add_edge(graph, node1, node2, dist):
|
||||||
""" Fügt eine Kante zwischen zwei Knoten im Graphen hinzu """
|
""" Fügt eine ungerichtete Kante zwischen zwei Knoten hinzu, aber nur einmal """
|
||||||
if node1 not in graph:
|
if node1 not in graph:
|
||||||
graph[node1] = []
|
graph[node1] = []
|
||||||
if node2 not in graph:
|
if node2 not in graph:
|
||||||
graph[node2] = []
|
graph[node2] = []
|
||||||
graph[node1].append((node2, dist))
|
|
||||||
graph[node2].append((node1, dist))
|
# Nur hinzufügen, wenn Kante noch nicht existiert (ungerichtet)
|
||||||
|
if not any(n == node2 for n, _ in graph[node1]):
|
||||||
|
graph[node1].append((node2, dist))
|
||||||
|
if not any(n == node1 for n, _ in graph[node2]):
|
||||||
|
graph[node2].append((node1, dist))
|
||||||
|
|
||||||
def project_point_on_segment(p, a, b):
|
def project_point_on_segment(p, a, b):
|
||||||
"""Projektion eines Punktes p auf ein Liniensegment a-b"""
|
""" Projektion eines Punktes p auf ein Liniensegment a-b """
|
||||||
ax, ay = a
|
ax, ay = a
|
||||||
bx, by = b
|
bx, by = b
|
||||||
px, py = p
|
px, py = p
|
||||||
@@ -65,6 +71,54 @@ def dijkstra(graph, start):
|
|||||||
|
|
||||||
return distances
|
return distances
|
||||||
|
|
||||||
|
def print_graph(graph):
|
||||||
|
printed = set()
|
||||||
|
for node, edges in graph.items():
|
||||||
|
for neighbor, dist in edges:
|
||||||
|
edge_id = tuple(sorted((node, neighbor)))
|
||||||
|
if edge_id not in printed:
|
||||||
|
printed.add(edge_id)
|
||||||
|
print(f"{edge_id[0]} --> {edge_id[1]} (Distanz: {dist})")
|
||||||
|
|
||||||
|
|
||||||
|
def visualize_graph(graph, racks):
|
||||||
|
G = nx.Graph()
|
||||||
|
pos = {}
|
||||||
|
|
||||||
|
for node, edges in graph.items():
|
||||||
|
pos[node] = node_to_coords(node, racks)
|
||||||
|
for neighbor, distance in edges:
|
||||||
|
if not G.has_edge(node, neighbor): # Doppelte Kanten vermeiden
|
||||||
|
G.add_edge(node, neighbor, weight=round(distance, 1))
|
||||||
|
|
||||||
|
plt.figure(figsize=(10, 10))
|
||||||
|
nx.draw(
|
||||||
|
G, pos,
|
||||||
|
with_labels=True,
|
||||||
|
node_size=100,
|
||||||
|
font_size=8,
|
||||||
|
node_color='skyblue',
|
||||||
|
edge_color='gray'
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_labels = nx.get_edge_attributes(G, 'weight')
|
||||||
|
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=6)
|
||||||
|
|
||||||
|
plt.title("Rack-Graph (aus racks.json)")
|
||||||
|
plt.axis("equal")
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
def node_to_coords(node_name, racks):
|
||||||
|
"""Extrahiert die Koordinaten aus dem Knotennamen wie 'Rack_1_Node_2'"""
|
||||||
|
parts = node_name.split("_")
|
||||||
|
rack = f"{parts[0]}_{parts[1]}"
|
||||||
|
node = f"{parts[2]}_{parts[3]}"
|
||||||
|
coords = racks[rack][node]
|
||||||
|
return tuple(coords)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(description='Berechne Wege von Sensoren zu Verteilern über Kabeltrassen')
|
parser = argparse.ArgumentParser(description='Berechne Wege von Sensoren zu Verteilern über Kabeltrassen')
|
||||||
@@ -83,32 +137,55 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
# Einlesen
|
# Einlesen
|
||||||
sensors = load_json(sensors_path)
|
sensors = load_json(sensors_path)
|
||||||
subdists = {k: parse_pos(v) for k, v in load_json(subdist_path).items()}
|
subdists = load_json(subdist_path)
|
||||||
racks = load_json(racks_path)
|
racks = load_json(racks_path)
|
||||||
|
|
||||||
# Graph erstellen
|
# Graph erstellen
|
||||||
graph = {}
|
graph = {}
|
||||||
|
|
||||||
# Sensoren zu Kabeltrassen verbinden
|
for rack_id, rack in racks.items():
|
||||||
for sensor_id, sensor_info in sensors.items(): #über alle Sensoren und alle deren Infos laufen
|
nodes = list(rack.values()) # Liste aller Knoten im Rack
|
||||||
sensor_pos = tuple(sensor_info['pos']) #sensor position als tuple übergeben
|
|
||||||
|
for i in range(len(nodes) - 1):
|
||||||
|
segment_start = tuple(nodes[i])
|
||||||
|
segment_end = tuple(nodes[i + 1])
|
||||||
|
dist = distance(segment_start, segment_end)
|
||||||
|
|
||||||
|
# Erstelle Kanten zwischen den benachbarten Knoten
|
||||||
|
add_edge(graph, f"{rack_id}_Node_{i+1}", f"{rack_id}_Node_{i+2}", dist)
|
||||||
|
|
||||||
|
# Graph in Kommandozeile beschreiben und mittels matplotlib ausgeben
|
||||||
|
print("\nGraph basierend auf den Racks (ungerichtet, eindeutige Kanten):")
|
||||||
|
print_graph(graph)
|
||||||
|
|
||||||
|
visualize_graph(graph, racks)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"""# 1. Vom Sensor zum Rack laufen und Knoten einfügen
|
||||||
|
for sensor_id, sensor_info in sensors.items():
|
||||||
|
sensor_pos = tuple(sensor_info['pos'])
|
||||||
for rack in racks:
|
for rack in racks:
|
||||||
for segment_start, segment_end in zip(rack[:-1], rack[1:]):
|
for segment_start, segment_end in zip(rack[:-1], rack[1:]):
|
||||||
# Berechne Distanz von Sensor zur Kabeltrasse
|
# Berechne Distanz von Sensor zur Kabeltrasse
|
||||||
px, py = project_point_on_segment(sensor_pos, segment_start, segment_end)
|
px, py = project_point_on_segment(sensor_pos, segment_start, segment_end)
|
||||||
dist = distance(sensor_pos, (px, py))
|
dist = distance(sensor_pos, (px, py))
|
||||||
add_edge(graph, sensor_id, f"rack_{rack}", dist)
|
rack_id = f"rack_{rack}"
|
||||||
|
# Sensor zum Rack Knoten verbinden
|
||||||
|
add_edge(graph, sensor_id, rack_id, dist)
|
||||||
|
|
||||||
# Unterverteiler zu Kabeltrassen verbinden
|
# 2. Vom Unterverteiler (UV) zum Rack laufen und Knoten einfügen
|
||||||
for uc_id, uc_pos in subdists.items():
|
for uc_id, uc_pos in subdists.items():
|
||||||
for rack in racks:
|
for rack in racks:
|
||||||
for segment_start, segment_end in zip(rack[:-1], rack[1:]):
|
for segment_start, segment_end in zip(rack[:-1], rack[1:]):
|
||||||
# Berechne Distanz von UC zur Kabeltrasse
|
# Berechne Distanz von UV zur Kabeltrasse
|
||||||
px, py = project_point_on_segment(uc_pos, segment_start, segment_end)
|
px, py = project_point_on_segment(uc_pos, segment_start, segment_end)
|
||||||
dist = distance(uc_pos, (px, py))
|
dist = distance(uc_pos, (px, py))
|
||||||
add_edge(graph, uc_id, f"rack_{rack}", dist)
|
rack_id = f"rack_{rack}"
|
||||||
|
# UV zum Rack Knoten verbinden
|
||||||
|
add_edge(graph, uc_id, rack_id, dist)
|
||||||
|
|
||||||
# Sensor zu UC verbinden (Routing von Sensoren zu den zugehörigen Unterverteilern)
|
# 3. Vom Sensor Knoten zum zugehörigen Unterverteiler Knoten entlang der Racks
|
||||||
for sensor_id, sensor_info in sensors.items():
|
for sensor_id, sensor_info in sensors.items():
|
||||||
subdist_id = None
|
subdist_id = None
|
||||||
if 'KENNZEICHNUNG' in sensor_info:
|
if 'KENNZEICHNUNG' in sensor_info:
|
||||||
@@ -120,14 +197,16 @@ if __name__ == "__main__":
|
|||||||
# Verbinde den Sensor mit dem zugehörigen Unterverteiler
|
# Verbinde den Sensor mit dem zugehörigen Unterverteiler
|
||||||
sensor_pos = tuple(sensor_info['pos'])
|
sensor_pos = tuple(sensor_info['pos'])
|
||||||
uc_pos = subdists[subdist_id]
|
uc_pos = subdists[subdist_id]
|
||||||
|
# Berechne Distanz von Sensor zum Unterverteiler (über Trassen)
|
||||||
dist = distance(sensor_pos, uc_pos)
|
dist = distance(sensor_pos, uc_pos)
|
||||||
add_edge(graph, sensor_id, subdist_id, dist)
|
add_edge(graph, sensor_id, subdist_id, dist)
|
||||||
|
|
||||||
# Berechnung der kürzesten Wege mit Dijkstra
|
# 4. Berechnung der kürzesten Wege mit Dijkstra
|
||||||
routing_result = {}
|
routing_result = {}
|
||||||
for sensor_id in sensors:
|
for sensor_id in sensors:
|
||||||
distances = dijkstra(graph, sensor_id)
|
distances = dijkstra(graph, sensor_id)
|
||||||
routing_result[sensor_id] = distances
|
routing_result[sensor_id] = distances
|
||||||
|
|
||||||
if args.console:
|
if args.console:
|
||||||
print(json.dumps(routing_result, indent=2))
|
print(json.dumps(routing_result, indent=2))"""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user