From ae86dbcafa92d3f10f684baade82996459174a02 Mon Sep 17 00:00:00 2001 From: mistangl Date: Fri, 9 May 2025 20:49:47 +0200 Subject: [PATCH] getpositions schreibt nur noch eine json Ergebnisdatei raus. Config launch.json und routing.py angepasst; in Requirements networkx aufgenommen. --- .vscode/launch.json | 16 ++++++++++- doc/Abstand_Punkt-Strecke.md | 54 ++++++++++++++++++++++++++++++++++++ lib/drawdxf.py | 4 +-- lib/getpositions.py | 12 ++++++-- lib/requirements.txt | 2 ++ lib/routing.py | 14 ++++++---- 6 files changed, 91 insertions(+), 11 deletions(-) create mode 100644 doc/Abstand_Punkt-Strecke.md diff --git a/.vscode/launch.json b/.vscode/launch.json index bef0309..19a058e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,7 @@ // Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { "name": "Python-Debugger: Aktuelle Datei mit Argumenten", "type": "debugpy", @@ -33,7 +34,8 @@ "-s", "-d", "-r", - "-c" + "-c", + "-w" ] }, { @@ -65,6 +67,18 @@ "-r" ] }, + { + "name": "run routing for easy", + "type": "debugpy", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal", + "justMyCode": true, + "args": [ + "--inputfile", + "easy_positions.json" + ] + }, { "name": "draw cable dxf from easy.json", "type": "debugpy", diff --git a/doc/Abstand_Punkt-Strecke.md b/doc/Abstand_Punkt-Strecke.md new file mode 100644 index 0000000..301a512 --- /dev/null +++ b/doc/Abstand_Punkt-Strecke.md @@ -0,0 +1,54 @@ +Um den Abstand eines Punktes $P$ von einer Strecke $\overline{AB}$ im zweidimensionalen Raum zu berechnen, gehst du wie folgt vor: + +--- + +### Gegeben: + +* Punkt $P = (x_0, y_0)$ +* Strecke mit den Endpunkten $A = (x_1, y_1)$, $B = (x_2, y_2)$ + +--- + +### Schritt-für-Schritt-Lösung: + +1. **Vektorbildung**: + + * $\vec{AP} = (x_0 - x_1, y_0 - y_1)$ + * $\vec{AB} = (x_2 - x_1, y_2 - y_1)$ + +2. **Skalare Projektion von $\vec{AP}$ auf $\vec{AB}$**: + + $$ + t = \frac{\vec{AP} \cdot \vec{AB}}{|\vec{AB}|^2} + $$ + +3. **Fallunterscheidung**: + + * Wenn $t < 0$: nächstgelegener Punkt ist $A$ + * Wenn $t > 1$: nächstgelegener Punkt ist $B$ + * Wenn $0 \leq t \leq 1$: Projektion fällt auf die Strecke, d.h. Punkt $Q = A + t \cdot \vec{AB}$ + +4. **Abstandsberechnung**: + + * Falls $t < 0$ oder $t > 1$: Abstand = $|P - A|$ bzw. $|P - B|$ + * Sonst: Abstand = $|P - Q|$ + +--- + +### Beispiel in Formel: + +$$ +\text{Abstand} = +\begin{cases} +\sqrt{(x_0 - x_1)^2 + (y_0 - y_1)^2}, & \text{wenn } t < 0 \\ +\sqrt{(x_0 - x_2)^2 + (y_0 - y_2)^2}, & \text{wenn } t > 1 \\ +\sqrt{(x_0 - x_q)^2 + (y_0 - y_q)^2}, & \text{sonst} +\end{cases} +$$ + +wobei: + +$$ +x_q = x_1 + t \cdot (x_2 - x_1), \quad y_q = y_1 + t \cdot (y_2 - y_1) +$$ + diff --git a/lib/drawdxf.py b/lib/drawdxf.py index 41ebe26..0d63b7d 100644 --- a/lib/drawdxf.py +++ b/lib/drawdxf.py @@ -6,7 +6,7 @@ from dataclasses import dataclass, asdict, fields from dacite import from_dict from typing import List from datetime import datetime -import shutil + @@ -73,7 +73,7 @@ def new_dxf(json_file, dxf_file, out_path): if __name__ == '__main__': parser = argparse.ArgumentParser(description='draws a dxf file with the given cable coordinates', prog='drawdxf') - parser.add_argument('-j', '--jsonfile', action='store', required=True, help='this json file contains all cables and its coordinates which should be drawn', metavar='myfile.json') + parser.add_argument('-j', '--jsonfile', action='store', required=True, help='this json file contains all cables and its coordinates which should be drawn. Saved with an unique timestamp', metavar='myfile.json') parser.add_argument('-d', '--dxf', action='store', required=True, help='this dxf drawing will be copied and the new layer with the cables will be added', metavar='myfile.dxf') args = parser.parse_args() diff --git a/lib/getpositions.py b/lib/getpositions.py index 69c86d7..6427a28 100644 --- a/lib/getpositions.py +++ b/lib/getpositions.py @@ -170,6 +170,7 @@ if __name__ == '__main__': parser.add_argument('-s', '--sensors', action='store_true', help='fetch all position of sensors, motors, actors') parser.add_argument('-d', '--dists', action='store_true', help='fetch all positions of all subdistributors') parser.add_argument('-r', '--rack', action='store_true', help='fetch all positions of all cable racks') + parser.add_argument('-w', '--write', action='store_true', help='write results into a json file') parser.add_argument('-c', '--console', action='store_true', help='print results to output') args = parser.parse_args() @@ -179,7 +180,8 @@ if __name__ == '__main__': config_dir = os.environ.get("PROJECT_CFG") filename = args.filename - doc = get_dxf_file(os.path.join(work_dir, filename)) # type: ignore + dxf_path = os.path.join(work_dir, filename) + doc = get_dxf_file(dxf_path) # type: ignore msp = doc.modelspace() res_pos = dict() @@ -190,21 +192,27 @@ if __name__ == '__main__': config = configparser.ConfigParser(allow_no_value=True) config.read(os.path.join(config_dir, "getpositions.cfg")) + output_results = dict() if args.sensors: res_pos = get_input_positions(msp) + output_results['sensors'] = res_pos if args.console: print(to_json(res_pos)) - write_results(to_json(res_pos), work_dir, "sensors.json") if args.dists: res_dist = get_subdistributor_positions(msp) + output_results['distributors'] = res_dist if args.console: print(to_json(res_dist)) write_results(to_json(res_dist), work_dir, "subdistributors.json") if args.rack: res_rac = get_rack_positions(msp) + output_results['racks'] = res_rac if args.console: print(to_json(res_rac)) write_results(to_json(res_rac), work_dir, "racks.json") + if args.write: + basename = os.path.splitext(args.filename)[0] + write_results(to_json(output_results), work_dir, basename+"_positions.json") else: parser.print_help() diff --git a/lib/requirements.txt b/lib/requirements.txt index 0fb1cc8..09641ab 100644 --- a/lib/requirements.txt +++ b/lib/requirements.txt @@ -1,2 +1,4 @@ +matplotlib=3.10.0 +networkx==3.4.2 dacite==1.9.2 ezdxf==1.4.1 diff --git a/lib/routing.py b/lib/routing.py index 30608c1..1a8b8ad 100644 --- a/lib/routing.py +++ b/lib/routing.py @@ -122,6 +122,7 @@ def node_to_coords(node_name, racks): if __name__ == "__main__": parser = argparse.ArgumentParser(description='Berechne Wege von Sensoren zu Verteilern über Kabeltrassen') + parser.add_argument('-i', '--inputfile', action='store', required=True, default="easy_position.json", help='file with all informations about positions gathered from getpositions', metavar='my_positions.json') parser.add_argument('-c', '--console', action='store_true', help='Ausgabe auf Konsole') args = parser.parse_args() @@ -131,14 +132,15 @@ if __name__ == "__main__": 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") + jsonfilename = args.inputfile + sensors_path = os.path.join(work_dir, jsonfilename) # Einlesen - sensors = load_json(sensors_path) - subdists = load_json(subdist_path) - racks = load_json(racks_path) + + data = load_json(sensors_path) + sensors = data["sensors"] + subdists = data["distributors"] + racks = data["racks"] # Graph erstellen graph = {}