Getpositions angepasst, sodass Jsons geschrieben werden. Ausserdem Anpassung, sodass Leichen (=Bloecke ohne pos) nicht erfasst werden
This commit is contained in:
+133
@@ -0,0 +1,133 @@
|
||||
import os
|
||||
import json
|
||||
import argparse
|
||||
import heapq
|
||||
import math
|
||||
|
||||
# Hilfsfunktionen
|
||||
def load_json(filepath):
|
||||
with open(filepath, 'r', encoding='utf-8') as f:
|
||||
return json.load(f)
|
||||
|
||||
def parse_pos(pos_str):
|
||||
""" Konvertiert '(x, y)' oder '(x, y, z)' in ein Tuple """
|
||||
try:
|
||||
return tuple(map(float, pos_str.strip('()').split(',')))
|
||||
except Exception:
|
||||
raise ValueError(f"Ungültiges Positionsformat: {pos_str}")
|
||||
|
||||
def distance(p1, p2):
|
||||
""" Euklidische Distanz in 2D """
|
||||
return math.sqrt((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2)
|
||||
|
||||
def add_edge(graph, node1, node2, dist):
|
||||
""" Fügt eine Kante zwischen zwei Knoten im Graphen hinzu """
|
||||
if node1 not in graph:
|
||||
graph[node1] = []
|
||||
if node2 not in graph:
|
||||
graph[node2] = []
|
||||
graph[node1].append((node2, dist))
|
||||
graph[node2].append((node1, dist))
|
||||
|
||||
def project_point_on_segment(p, a, b):
|
||||
"""Projektion eines Punktes p auf ein Liniensegment a-b"""
|
||||
ax, ay = a
|
||||
bx, by = b
|
||||
px, py = p
|
||||
|
||||
dx = bx - ax
|
||||
dy = by - ay
|
||||
if dx == dy == 0:
|
||||
return a
|
||||
|
||||
t = ((px - ax) * dx + (py - ay) * dy) / (dx * dx + dy * dy)
|
||||
t = max(0, min(1, t)) # Begrenze t auf [0,1]
|
||||
return (ax + t * dx, ay + t * dy)
|
||||
|
||||
def dijkstra(graph, start):
|
||||
""" Dijkstra-Algorithmus, um die kürzesten Wege im Graphen zu berechnen """
|
||||
distances = {node: float('inf') for node in graph}
|
||||
distances[start] = 0
|
||||
priority_queue = [(0, start)] # (Distanz, Knoten)
|
||||
|
||||
while priority_queue:
|
||||
current_distance, current_node = heapq.heappop(priority_queue)
|
||||
|
||||
if current_distance > distances[current_node]:
|
||||
continue
|
||||
|
||||
for neighbor, weight in graph[current_node]:
|
||||
distance = current_distance + weight
|
||||
|
||||
if distance < distances[neighbor]:
|
||||
distances[neighbor] = distance
|
||||
heapq.heappush(priority_queue, (distance, neighbor))
|
||||
|
||||
return distances
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='Berechne Wege von Sensoren zu Verteilern über Kabeltrassen')
|
||||
parser.add_argument('-c', '--console', action='store_true', help='Ausgabe auf Konsole')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Umgebungsvariablen
|
||||
work_dir = os.environ.get("PROJECT_WORK")
|
||||
config_dir = os.environ.get("PROJECT_CFG")
|
||||
|
||||
# Pfade zu JSON-Dateien
|
||||
sensors_path = os.path.join(work_dir, "sensors.json")
|
||||
subdist_path = os.path.join(work_dir, "subdistributors.json")
|
||||
racks_path = os.path.join(work_dir, "racks.json")
|
||||
|
||||
# Einlesen
|
||||
sensors = load_json(sensors_path)
|
||||
subdists = {k: parse_pos(v) for k, v in load_json(subdist_path).items()}
|
||||
racks = load_json(racks_path)
|
||||
|
||||
# Graph erstellen
|
||||
graph = {}
|
||||
|
||||
# Sensoren zu Kabeltrassen verbinden
|
||||
for sensor_id, sensor_info in sensors.items(): #über alle Sensoren und alle deren Infos laufen
|
||||
sensor_pos = tuple(sensor_info['pos']) #sensor position als tuple übergeben
|
||||
for rack in racks:
|
||||
for segment_start, segment_end in zip(rack[:-1], rack[1:]):
|
||||
# Berechne Distanz von Sensor zur Kabeltrasse
|
||||
px, py = project_point_on_segment(sensor_pos, segment_start, segment_end)
|
||||
dist = distance(sensor_pos, (px, py))
|
||||
add_edge(graph, sensor_id, f"rack_{rack}", dist)
|
||||
|
||||
# Unterverteiler zu Kabeltrassen verbinden
|
||||
for uc_id, uc_pos in subdists.items():
|
||||
for rack in racks:
|
||||
for segment_start, segment_end in zip(rack[:-1], rack[1:]):
|
||||
# Berechne Distanz von UC zur Kabeltrasse
|
||||
px, py = project_point_on_segment(uc_pos, segment_start, segment_end)
|
||||
dist = distance(uc_pos, (px, py))
|
||||
add_edge(graph, uc_id, f"rack_{rack}", dist)
|
||||
|
||||
# Sensor zu UC verbinden (Routing von Sensoren zu den zugehörigen Unterverteilern)
|
||||
for sensor_id, sensor_info in sensors.items():
|
||||
subdist_id = None
|
||||
if 'KENNZEICHNUNG' in sensor_info:
|
||||
for uc_id in subdists:
|
||||
if uc_id in sensor_info['KENNZEICHNUNG']:
|
||||
subdist_id = uc_id
|
||||
break
|
||||
if subdist_id:
|
||||
# Verbinde den Sensor mit dem zugehörigen Unterverteiler
|
||||
sensor_pos = tuple(sensor_info['pos'])
|
||||
uc_pos = subdists[subdist_id]
|
||||
dist = distance(sensor_pos, uc_pos)
|
||||
add_edge(graph, sensor_id, subdist_id, dist)
|
||||
|
||||
# Berechnung der kürzesten Wege mit Dijkstra
|
||||
routing_result = {}
|
||||
for sensor_id in sensors:
|
||||
distances = dijkstra(graph, sensor_id)
|
||||
routing_result[sensor_id] = distances
|
||||
|
||||
if args.console:
|
||||
print(json.dumps(routing_result, indent=2))
|
||||
Reference in New Issue
Block a user