STR tree Generierung jetzt innerhalb der Rack-verwaltenden Klasse. Finden und Anpinnen von Racks über STR tree

This commit is contained in:
2025-05-27 12:07:03 +02:00
parent 66cb58fbfc
commit 9cacf95870
+53 -17
View File
@@ -115,6 +115,8 @@ class RackIDs():
self._rack2begend = dict()
# Toleranzen zur Rack anbindung aneinander (Rack Snap)
self._tol_snap = tol_snap
# falls man die rack zu den Sensorpunkten abfragen möchte, ist ein STR Baum nötig
self._rack_tree = None
def add_rack(self, beg:Point, end:Point, name:str): #Hier wird Rack nur mit Anfang und Ende hinzugefügt -> wie macht man Zwischenpunkte?
if beg in self._point2rack:
@@ -209,6 +211,50 @@ class RackIDs():
connrackname = f"c-{rnames[l2]}"
self.add_rack(last, snap_point, connrackname)
def _build_rack_strtree(self):
self._rack_lines = []
self._rack_map = {}
for r_name, pts in self.get_racks_borders().items():
line = LineString([pts[0], pts[-1]])
self._rack_lines.append(line)
self._rack_map[line] = r_name
self._rack_tree = STRtree(self._rack_lines)
def join_racks_str(self):
if self._rack_tree is None:
self._build_rack_strtree()
rack_tree = self._rack_tree
rnames = self._rack_map
allracks = self._rack_lines
# Erzeugung von BoundingBox
for i, l1 in enumerate(allracks):
bbox = box(*l1.bounds).buffer(self._tol_snap)
candidates = rack_tree.query(bbox)
candidates = [self._rack_lines[idx] for idx in candidates]
for l2 in candidates:
if l1.equals(l2):
continue
# Echte Schnittpunkte
if l1.intersects(l2):
inter = l1.intersection(l2)
if inter.geom_type == "Point":
self.add_point_to_rack(inter, rnames[l1])
self.add_point_to_rack(inter, rnames[l2])
# Beinahe Schnittpunkte -> Snapping
for pt in [Point(l2.coords[0]), Point(l2.coords[-1])]:
if l1.distance(pt) <= self._tol_snap:
snap_point = l1.interpolate(l1.project(pt))
self.add_point_to_rack(snap_point, rnames[l1])
connrackname = f"c-{rnames[l2]}"
self.add_rack(pt, snap_point, connrackname)
def rack_is_horizontal(self, name):
[pa, pe] = self._rack2begend[name]
if pa.y == pe.y:
@@ -288,8 +334,7 @@ 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"""
@@ -387,29 +432,20 @@ class Anlage():
return self.connect_equipment_to_racks(self._distributors, self._distributors_onpoints)
def join_racks(self):
self._racks.join_racks()
def _build_rack_strtree(self):
self._rack_lines = []
self._rack_map = {}
for r_name, pts in self._racks.get_racks_borders().items():
line = LineString([pts[0], pts[-1]])
self._rack_lines.append(line)
self._rack_map[line] = r_name
self._rack_tree = STRtree(self._rack_lines)
self._racks.join_racks_str()
def find_nearest_rack_from_point_STR_bbox(self, max_dist, sensor:Point) -> tuple[Point, str]:
if self._rack_tree is None:
self._build_rack_strtree()
if self._racks._rack_tree is None:
self._racks._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(bbox)
candidates = self._racks._rack_tree.query(bbox)
if len(candidates) == 0:
raise LookupError("no candidates in box found")
candidates = [self._rack_lines[idx] for idx in candidates]
candidates = [self._racks._rack_lines[idx] for idx in candidates]
best_dist = max_dist
best_line = candidates[0]
for line in candidates:
@@ -418,7 +454,7 @@ class Anlage():
best_dist = dist
best_line = line
rack_name = self._rack_map[best_line]
rack_name = self._racks._rack_map[best_line]
nearest_point = best_line.interpolate(best_line.project(sensor))
return nearest_point, rack_name