From dd5cf2d6a84da39188cda5b498699fae9e368257 Mon Sep 17 00:00:00 2001 From: "Tammo.Weber" Date: Thu, 5 Feb 2026 21:43:26 +0100 Subject: [PATCH] merge --- GHA_triaxial/gha2_num.py | 1 - dashboard.py | 134 ++++++++++++++++++++++++++------------- 2 files changed, 91 insertions(+), 44 deletions(-) diff --git a/GHA_triaxial/gha2_num.py b/GHA_triaxial/gha2_num.py index c898cfc..b912ba1 100644 --- a/GHA_triaxial/gha2_num.py +++ b/GHA_triaxial/gha2_num.py @@ -383,7 +383,6 @@ def gha2_num( return alpha_1, alpha_2, s, beta_arr, lamb_arr - # all_points == False (schnell) _, y_end, s = rk4_last_with_integral(ode_lamb, lamb_1, startwerte_final, dlamb, N, integrand_lambda) beta_end, beta_p_end, _, _ = y_end diff --git a/dashboard.py b/dashboard.py index 7abadd1..f30c35f 100644 --- a/dashboard.py +++ b/dashboard.py @@ -1,4 +1,4 @@ -from dash import Dash, html, dcc, Input, Output, State, no_update +from dash import Dash, dash, html, dcc, Input, Output, State, no_update, ctx import plotly.graph_objects as go import numpy as np import dash_bootstrap_components as dbc @@ -12,6 +12,7 @@ import ausgaben as aus from GHA_triaxial.gha1_ana import gha1_ana from GHA_triaxial.gha1_num import gha1_num +from GHA_triaxial.gha1_ES import gha1_ES from GHA_triaxial.gha1_approx import gha1_approx from GHA_triaxial.gha2_num import gha2_num @@ -23,6 +24,7 @@ app = Dash(__name__, suppress_callback_exceptions=True, external_stylesheets=[db app.title = "Geodätische Hauptaufgaben" +# Erzeugen der Eingabefelder def inputfeld(left_text, input_id, right_text="", width=200, min=None, max=None): return html.Div( children=[ @@ -42,6 +44,7 @@ def inputfeld(left_text, input_id, right_text="", width=200, min=None, max=None) style={"display": "flex", "alignItems": "center", "marginBottom": "10px"}, ) +# Erzeugen der Checklisten inkl. Eingabefelder def method_row(label, cb_id, input_id=None, value="", info=""): base_row_style = { "display": "flex", @@ -102,8 +105,6 @@ def method_row(label, cb_id, input_id=None, value="", info=""): return html.Div(children, style=base_row_style) - - def ellipsoid_figure(ell: EllipsoidTriaxial, title="Dreiachsiges Ellipsoid"): fig = go.Figure() @@ -228,11 +229,12 @@ def figure_points(fig, points): )) return fig -def figure_lines(fig, line, color): +def figure_lines(fig, line, name, color): """ :param fig: plotly.graph_objects.Figure :param line: Punktliste [[x1,y1,z1], [x2,y2,z2]] + :param name: Name :param color: Farbe :return: plotly.graph_objects.Figure """ @@ -242,10 +244,12 @@ def figure_lines(fig, line, color): x=points[:, 0], y=points[:, 1], z=points[:, 2], mode="lines", line=dict(width=4, color=color), - name="Strecke", showlegend=False + name=name, showlegend=False )) return fig +# HTML der beiden Tabs +# Tab 1 pane_gha1 = html.Div( [ inputfeld("β₀", "input-GHA1-beta0", "°", min=-90, max=90), @@ -255,6 +259,7 @@ pane_gha1 = html.Div( method_row("Analytisch", "cb-ana-1", "input-ana-1", ""), method_row("Numerisch", "cb-num-1", "input-num-n-1", "2000", info="Anzahl Schritte"), + method_row("Stochastisch (ES)", "cb-stoch-1", "input-stoch-n-1", "1000", info="Info"), method_row("Approximiert", "cb-approx-1", "input-approx-ds-1", "1000", info="Länge Streckensegment [m]"), @@ -287,6 +292,7 @@ pane_gha1 = html.Div( style={"display": "block"}, ) +# Tab2 pane_gha2 = html.Div( [ inputfeld("β₀", "input-GHA2-beta0", "°", min=-90, max=90), @@ -295,7 +301,7 @@ pane_gha2 = html.Div( inputfeld("λ₁", "input-GHA2-lamb1", "°", min=-180, max=180), method_row("Numerisch", "cb-num-2", "input-num-n-2", "2000", info="Anzahl Schritte"), - method_row("Stochastisch", "cb-stoch-2", "input-stoch-2", ""), + method_row("Stochastisch", "cb-stoch-2", "input-stoch-n-2", "1000", info="Info"), method_row("Approximiert", "cb-approx-2", "input-approx-ds-2", "1000", info="Länge Streckensegment [m]"), html.Div( @@ -326,7 +332,7 @@ pane_gha2 = html.Div( ) -# HTML-Elemente +# HTML-Gerüst app.layout = html.Div( style={"fontFamily": "Arial", "padding": "10px", "width": "95%", "margin": "0 auto"}, children=[ @@ -342,6 +348,7 @@ app.layout = html.Div( }, children=[ + # Linker Bereich html.Div( style={"flex": "1 1 420px", "maxWidth": "640px"}, children=[ @@ -387,6 +394,7 @@ app.layout = html.Div( ], ), + # Rechter Bereich html.Div( style={ "flex": "1 1 750px", @@ -452,6 +460,21 @@ def switch_tabs(tab): show2 = {"display": "block"} if tab == "tab-GHA2" else {"display": "none"} return show1, show2 +# Funktionen zum Aktivieren der Eingabefelder innerhalb der Checklisten +@app.callback( + Output("input-num-n-1", "disabled"), + Input("cb-num-1", "value"), +) +def toggle_ds(v): + return "on" not in (v or []) + +@app.callback( + Output("input-stoch-n-1", "disabled"), + Input("cb-stoch-1", "value"), +) +def toggle_ds(v): + return "on" not in (v or []) + @app.callback( Output("input-approx-ds-1", "disabled"), Input("cb-approx-1", "value"), @@ -459,9 +482,17 @@ def switch_tabs(tab): def toggle_ds(v): return "on" not in (v or []) + @app.callback( - Output("input-num-n-1", "disabled"), - Input("cb-num-1", "value"), + Output("input-num-n-2", "disabled"), + Input("cb-num-2", "value"), +) +def toggle_ds(v): + return "on" not in (v or []) + +@app.callback( + Output("input-stoch-n-2", "disabled"), + Input("cb-stoch-2", "value"), ) def toggle_ds(v): return "on" not in (v or []) @@ -473,21 +504,9 @@ def toggle_ds(v): def toggle_ds(v): return "on" not in (v or []) -@app.callback( - Output("input-num-n-2", "disabled"), - Input("cb-num-2", "value"), -) -def toggle_ds(v): - return "on" not in (v or []) - -@app.callback( - Output("input-stoch-2", "disabled"), - Input("cb-stoch-2", "value"), -) -def toggle_ds(v): - return "on" not in (v or []) +# Abfrage ob Berechnungsverfahren gewählt @app.callback( Output("tabs-GHA1-out", "children"), Input("button-calc-gha1", "n_clicks"), @@ -528,8 +547,7 @@ def compute_gha1_ana(n1, cb_ana, beta0, lamb0, s, a0, ax, ay, b): #if not method1: #return html.Span("Bitte Berechnungsverfahren wählen.", style={"color": "red"}), None if "on" not in (cb_ana or []): - return out, no_update - + return "", None ell = EllipsoidTriaxial(ax, ay, b) beta_rad = wu.deg2rad(float(beta0)) @@ -576,8 +594,8 @@ def compute_gha1_ana(n1, cb_ana, beta0, lamb0, s, a0, ax, ay, b): def compute_gha1_num(n1, cb_num, n_in, beta0, lamb0, s, a0, ax, ay, b): if not n1: return no_update, no_update - if not n1 or "on" not in (cb_num or []): - return no_update, no_update + if "on" not in (cb_num or []): + return "", None n_in = int(n_in) if n_in else 2000 @@ -614,6 +632,8 @@ def compute_gha1_num(n1, cb_num, n_in, beta0, lamb0, s, a0, ax, ay, b): Output("output-gha1-stoch", "children"), Output("store-gha1-stoch", "data"), Input("button-calc-gha1", "n_clicks"), + State("cb-stoch-1", "value"), + State("input-stoch-n-1", "value"), State("input-GHA1-beta0", "value"), State("input-GHA1-lamb0", "value"), State("input-GHA1-s", "value"), @@ -624,11 +644,13 @@ def compute_gha1_num(n1, cb_num, n_in, beta0, lamb0, s, a0, ax, ay, b): State("method-checklist-1", "value"), prevent_initial_call=True, ) -def compute_gha1_stoch(n1, beta0, lamb0, s, a0, ax, ay, b, method1): +def compute_gha1_stoch(n1, cb_stoch, n_in, beta0, lamb0, s, a0, ax, ay, b, method1): if not n1: return no_update, no_update - if "stochastisch" not in (method1 or []): - return no_update, no_update + if "on" not in (cb_stoch or []): + return "", None + + n_in = int(n_in) if n_in else 100 ell = EllipsoidTriaxial(ax, ay, b) beta_rad = wu.deg2rad(float(beta0)) @@ -636,7 +658,7 @@ def compute_gha1_stoch(n1, beta0, lamb0, s, a0, ax, ay, b, method1): alpha_rad = wu.deg2rad(float(a0)) s_val = float(s) - betas, lambs, alphas, S_real = gha1_es( + betas, lambs, alphas, S_real = gha1_ES( beta_rad, lamb_rad, alpha_rad, s_val, 10000, @@ -682,7 +704,7 @@ def compute_gha1_approx(n1, cb_approx, ds_in, beta0, lamb0, s, a0, ax, ay, b): if not n1: return no_update, no_update if not n1 or "on" not in (cb_approx or []): - return no_update, no_update + return "", None ds_in = int(ds_in) if ds_in else 1000 @@ -740,7 +762,7 @@ def compute_gha2_num(n2, cb_num, n_in, beta0, lamb0, beta1, lamb1, ax, ay, b): if None in (beta0, lamb0, beta1, lamb1): return html.Span("Bitte β₀, λ₀, β₁ und λ₁ eingeben.", style={"color": "red"}), None if "on" not in (cb_num or []): - return no_update, no_update + return "", None n_in = int(n_in) if n_in else 2000 @@ -770,6 +792,7 @@ def compute_gha2_num(n2, cb_num, n_in, beta0, lamb0, beta1, lamb1, ax, ay, b): store = { "points": [("P0", P0, "black"), ("P1", P1, "black")], "polyline": polyline, + "name": "numerisch", "color": "#ff8c00", } return out, store @@ -779,7 +802,7 @@ def compute_gha2_num(n2, cb_num, n_in, beta0, lamb0, beta1, lamb1, ax, ay, b): Output("store-gha2-stoch", "data"), Input("button-calc-gha2", "n_clicks"), State("cb-stoch-2", "value"), - State("input-stoch-2", "value"), + State("input-stoch-n-2", "value"), State("input-GHA2-beta0", "value"), State("input-GHA2-lamb0", "value"), State("input-GHA2-beta1", "value"), @@ -789,11 +812,13 @@ def compute_gha2_num(n2, cb_num, n_in, beta0, lamb0, beta1, lamb1, ax, ay, b): State("input-b", "value"), prevent_initial_call=True, ) -def compute_gha2_stoch(n2, cb_stoch, n_stoch, beta0, lamb0, beta1, lamb1, ax, ay, b): +def compute_gha2_stoch(n2, cb_stoch, n_in, beta0, lamb0, beta1, lamb1, ax, ay, b): if not n2: return no_update, no_update if "on" not in (cb_stoch or []): - return no_update, no_update + return "", None + + n_in = int(n_in) if n_in else 1000 ell = EllipsoidTriaxial(ax, ay, b) @@ -812,8 +837,14 @@ def compute_gha2_stoch(n2, cb_stoch, n_stoch, beta0, lamb0, beta1, lamb1, ax, ay html.Span(f"{aus.gms('α₀', a0_stoch, 4)}, α₁ = {a1_stoch}, s = {s_stoch:.4f} m"), ]) + store = { + "points": [("P0", P0, "black"), ("P1", P1, "black")], + "polyline": points, + "name": "stochastisch (ES)", + "color": "#d62728", + } - return out, {"points": None, "polyline": None, "color": "#d62728"} + return out, store @app.callback( Output("output-gha2-approx", "children"), @@ -834,7 +865,7 @@ def compute_gha2_approx(n2, cb_approx, ds_in, beta0, lamb0, beta1, lamb1, ax, ay if not n2: return no_update, no_update if "on" not in (cb_approx or []): - return no_update, no_update + return "", None ds_in = int(ds_in) if ds_in else 1000 @@ -858,6 +889,7 @@ def compute_gha2_approx(n2, cb_approx, ds_in, beta0, lamb0, beta1, lamb1, ax, ay store = { "points": [("P0", P0, "black"), ("P1", P1, "black")], "polyline": points, + "name": "aproximiert", "color": "#00c2fc", } @@ -870,6 +902,8 @@ def compute_gha2_approx(n2, cb_approx, ds_in, beta0, lamb0, beta1, lamb1, ax, ay Input("input-ay", "value"), Input("input-b", "value"), Input("dropdown-coors-type", "value"), + Input("button-calc-gha1", "n_clicks"), + Input("button-calc-gha2", "n_clicks"), Input("store-gha1-ana", "data"), Input("store-gha1-num", "data"), Input("store-gha1-stoch", "data"), @@ -878,34 +912,48 @@ def compute_gha2_approx(n2, cb_approx, ds_in, beta0, lamb0, beta1, lamb1, ax, ay Input("store-gha2-stoch", "data"), Input("store-gha2-approx", "data"), ) -def render_all(ax, ay, b, coords_type, store_gha1_ana, store_gha1_num, store_gha1_stoch, store_gha1_approx, store_gha2_num, store_gha2_stoch, store_gha2_approx): +def render_all(ax, ay, b, coords_type, + n_clicks_gha1, n_clicks_gha2, + store_gha1_ana, store_gha1_num, store_gha1_stoch, store_gha1_approx, + store_gha2_num, store_gha2_stoch, store_gha2_approx): + if None in (ax, ay, b): return go.Figure() + n1 = n_clicks_gha1 or 0 + n2 = n_clicks_gha2 or 0 + ell = EllipsoidTriaxial(ax, ay, b) fig = ellipsoid_figure(ell, title="") fig = figure_constant_lines(fig, ell, coords_type) - def add_from_store(fig, store): + def add_from_store(fig, store, expected_calc_id): if not store: return fig + if store.get("calc_id") != expected_calc_id: + return fig pts = store.get("points") or [] if pts: fig = figure_points(fig, pts) line = store.get("polyline") + name = store.get("name", "") if line: - fig = figure_lines(fig, line, store.get("color", "#ff8c00")) + fig = figure_lines(fig, line, name, store.get("color", "#ff8c00")) return fig - for st in (store_gha1_ana, store_gha1_num, store_gha1_stoch, store_gha1_approx, store_gha2_num, store_gha2_stoch, store_gha2_approx): - fig = add_from_store(fig, st) + for st in (store_gha1_ana, store_gha1_num, store_gha1_stoch, store_gha1_approx): + fig = add_from_store(fig, st, n1) + + for st in (store_gha2_num, store_gha2_stoch, store_gha2_approx): + fig = add_from_store(fig, st, n2) return fig + if __name__ == "__main__": + # Automatisiertes Öffnen der Seite im Browser HOST = "127.0.0.1" PORT = 8050 - #Timer(1.0, webbrowser.open_new_tab(f"http://{HOST}:{PORT}/")).start app.run(host=HOST, port=PORT, debug=False)