From 9cacf958704e72a9f4f82159bd262e841b0b411c Mon Sep 17 00:00:00 2001 From: lertlmaier Date: Tue, 27 May 2025 12:07:03 +0200 Subject: [PATCH] =?UTF-8?q?STR=20tree=20Generierung=20jetzt=20innerhalb=20?= =?UTF-8?q?der=20Rack-verwaltenden=20Klasse.=20Finden=20und=20Anpinnen=20v?= =?UTF-8?q?on=20Racks=20=C3=BCber=20STR=20tree?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/plant.py | 70 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 17 deletions(-) diff --git a/lib/plant.py b/lib/plant.py index b99b478..c72e3e5 100644 --- a/lib/plant.py +++ b/lib/plant.py @@ -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