Merge remote-tracking branch 'origin/main'

This commit is contained in:
2026-02-06 16:25:40 +01:00

View File

@@ -264,10 +264,10 @@ def figure_lines(fig, line, name, color):
# Tab 1
pane_gha1 = html.Div(
[
inputfeld("β₀", "input-GHA1-beta0", "°", min=-90, max=90),
inputfeld("λ₀", "input-GHA1-lamb0", "°", min=-180, max=180),
inputfeld("s", "input-GHA1-s", "m", min=0),
inputfeld("α₀", "input-GHA1-a", "°", min=0, max=360),
inputfeld("β₀", "input-GHA1-beta0", "°"),
inputfeld("λ₀", "input-GHA1-lamb0", "°"),
inputfeld("s", "input-GHA1-s", "m"),
inputfeld("α₀", "input-GHA1-a", "°"),
method_row("Analytisch", "cb-ana-1", "input-ana-1", "70", info="Ordnung"),
method_row("Numerisch", "cb-num-1", "input-num-n-1", "2000", info="Anzahl Schritte"),
@@ -308,10 +308,10 @@ pane_gha1 = html.Div(
# Tab2
pane_gha2 = html.Div(
[
inputfeld("β₀", "input-GHA2-beta0", "°", min=-90, max=90),
inputfeld("λ₀", "input-GHA2-lamb0", "°", min=-180, max=180),
inputfeld("β₁", "input-GHA2-beta1", "°", min=-90, max=90),
inputfeld("λ₁", "input-GHA2-lamb1", "°", min=-180, max=180),
inputfeld("β₀", "input-GHA2-beta0", "°"),
inputfeld("λ₀", "input-GHA2-lamb0", "°"),
inputfeld("β₁", "input-GHA2-beta1", "°"),
inputfeld("λ₁", "input-GHA2-lamb1", "°"),
method_row("Numerisch", "cb-num-2", "input-num-n-2", "2000", info="Anzahl Schritte"),
method_row("Stochastisch", "cb-stoch-2", "input-stoch-n-2", "1000", info="Länge Streckensegment [m]"),
@@ -387,11 +387,12 @@ app.layout = html.Div(
),
html.P("Halbachsen:", style={"marginBottom": "10px"}),
inputfeld("aₓ", "input-ax", "m", min=0),
inputfeld("aᵧ", "input-ay", "m", min=0),
inputfeld("b", "input-b", "m", min=0),
inputfeld("aₓ", "input-ax", "m"),
inputfeld("aᵧ", "input-ay", "m"),
inputfeld("b", "input-b", "m"),
html.Div(id="axes-error", style={"marginLeft": "10px", "marginTop": "5px", "marginBottom": "10px"}),
html.Br(),
#html.Br(),
dcc.Tabs(
id="tabs-GHA",
@@ -460,13 +461,10 @@ app.layout = html.Div(
)
def fill_inputs_from_dropdown(selected_ell):
if not selected_ell:
return None, None, None
return no_update, no_update, no_update
ell = EllipsoidTriaxial.init_name(selected_ell)
ax = ell.ax
ay = ell.ay
b = ell.b
return ax, ay, b
return ell.ax, ell.ay, ell.b
# Funktion zur Generierung der Tab-Inhalte
@app.callback(
@@ -540,11 +538,76 @@ def toggle_ds(v):
State("cb-num-1", "value"),
State("cb-stoch-1", "value"),
State("cb-approx-1", "value"),
# Eingaben GHA1
State("input-GHA1-beta0", "value"),
State("input-GHA1-lamb0", "value"),
State("input-GHA1-s", "value"),
State("input-GHA1-a", "value"),
# Halbachsen
State("input-ax", "value"),
State("input-ay", "value"),
State("input-b", "value"),
prevent_initial_call=True,
)
def gha1_method_hint(n, a, nu, st, ap):
def gha1_method_hint(n, a, nu, st, ap, beta0, lamb0, s, a0, ax, ay, b):
# Ellipsoid
if ax is None or ay is None or b is None:
return html.Span("Bitte Ellipsoid wählen bzw. Halbachsen eingeben.", style={"color": "red"})
# Halbachsen
try:
ax_f, ay_f, b_f = float(ax), float(ay), float(b)
except (TypeError, ValueError):
return html.Span("Bitte gültige Zahlen für aₓ, aᵧ und b eingeben.", style={"color": "red"})
if ax_f <= 0 or ay_f <= 0 or b_f <= 0:
return html.Span("Halbachsen müssen > 0 sein.", style={"color": "red"})
if not (ax_f >= ay_f >= b_f):
return html.Span("Ungültige Halbachsen! (aₓ ≥ aᵧ ≥ b)", style={"color": "red"})
# GHA1-Eingabefelder prüfen
missing = []
if beta0 is None:
missing.append("β₀")
if lamb0 is None:
missing.append("λ₀")
if s is None:
missing.append("s")
if a0 is None:
missing.append("α₀")
if missing:
return html.Span(
"Bitte " + ", ".join(missing) + " eingeben.",
style={"color": "red"},
)
# Berechnungsverfahren
any_on = any("on" in (v or []) for v in (a, nu, st, ap))
return "" if any_on else html.Span("Bitte Berechnungsverfahren wählen.", style={"color": "red"})
if not any_on:
return html.Span("Bitte Berechnungsverfahren wählen.", style={"color": "red"})
# Eingaben Wertebereiche
try:
beta0_f = float(beta0)
lamb0_f = float(lamb0)
s_f = float(s)
a0_f = float(a0)
except (TypeError, ValueError):
return html.Span("Bitte gültige Zahlen für β₀, λ₀, s und α₀ eingeben.", style={"color": "red"})
if not (-90 <= beta0_f <= 90):
return html.Span("β₀ muss im Bereich [-90°, 90°] liegen.", style={"color": "red"})
if not (-180 <= lamb0_f <= 180):
return html.Span("λ₀ muss im Bereich [-180°, 180°] liegen.", style={"color": "red"})
if s_f <= 0:
return html.Span("s muss > 0 sein.", style={"color": "red"})
if not (0 <= a0_f <= 360):
return html.Span("α₀ muss im Bereich [0°, 360°] liegen.", style={"color": "red"})
return ""
# -- GHA 1 ---
@app.callback(
@@ -565,10 +628,6 @@ def gha1_method_hint(n, a, nu, st, ap):
def compute_gha1_ana(n1, cb_ana, n_in, beta0, lamb0, s, a0, ax, ay, b):
if not n1:
return no_update, no_update
if None in (ax, ay, b):
return html.Span("Bitte Ellipsoid wählen.", style={"color": "red"}), None
if None in (beta0, lamb0, s, a0):
return html.Span("Bitte β₀, λ₀, s und α₀ eingeben.", style={"color": "red"}), None
if "on" not in (cb_ana or []):
return "", None
@@ -774,10 +833,6 @@ def compute_gha1_approx(n1, cb_approx, ds_in, beta0, lamb0, s, a0, ax, ay, b):
def compute_gha2_num(n2, cb_num, n_in, beta0, lamb0, beta1, lamb1, ax, ay, b):
if not n2:
return no_update, no_update
if None in (ax, ay, b):
return html.Span("Bitte Ellipsoid wählen.", style={"color": "red"}), None
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 "", None
@@ -936,6 +991,17 @@ def render_all(ax, ay, b, coords_type, tab, t1, t2,
if None in (ax, ay, b):
return go.Figure()
try:
ax = float(ax); ay = float(ay); b = float(b)
except (TypeError, ValueError):
return go.Figure()
if ax <= 0 or ay <= 0 or b <= 0:
return go.Figure()
if not (ax >= ay >= b):
return go.Figure()
ell = EllipsoidTriaxial(ax, ay, b)
fig = ellipsoid_figure(ell, title="")
@@ -1012,7 +1078,7 @@ def render_all(ax, ay, b, coords_type, tab, t1, t2,
yanchor="bottom",
y=1.02,
xanchor="left",
x=0.0,
x=0.06,
),
)
@@ -1100,6 +1166,62 @@ def set_gha1_header(_):
def set_gha2_header(_):
return html.H4("Zweite Hauptaufgabe")
# Funktion zur Überprüfung der Halbachsen
@app.callback(
Output("axes-error", "children"),
Output("button-calc-gha1", "disabled"),
Output("button-calc-gha2", "disabled"),
Input("input-ax", "value"),
Input("input-ay", "value"),
Input("input-b", "value"),
)
def validate_axes(ax, ay, b):
if ax is None or ay is None or b is None:
return "", True, True
try:
ax = float(ax)
ay = float(ay)
b = float(b)
except (TypeError, ValueError):
return html.Span("Bitte gültige Zahlen für aₓ, aᵧ und b eingeben.", style={"color": "red"}), True, True
if ax <= 0 or ay <= 0 or b <= 0:
return html.Span("Halbachsen müssen > 0 sein.", style={"color": "red"}), True, True
if not (ax >= ay >= b):
return html.Span("Ungültige Halbachsen! (aₓ ≥ aᵧ ≥ b)", style={"color": "red"}), True, True
return "", False, False
# Leeren des Dropdowns
@app.callback(
Output("dropdown-ellipsoid", "value"),
Input("input-ax", "value"),
Input("input-ay", "value"),
Input("input-b", "value"),
State("dropdown-ellipsoid", "value"),
prevent_initial_call=True,
)
def clear_dropdown_if_axes_changed(ax, ay, b, selected_ell):
if not selected_ell:
return no_update
if ax is None or ay is None or b is None:
return ""
try:
ax = float(ax); ay = float(ay); b = float(b)
ell = EllipsoidTriaxial.init_name(selected_ell)
same = (
np.isclose(ax, float(ell.ax), rtol=0, atol=1e-9) and
np.isclose(ay, float(ell.ay), rtol=0, atol=1e-9) and
np.isclose(b, float(ell.b), rtol=0, atol=1e-9)
)
except Exception:
return ""
return no_update if same else ""
if __name__ == "__main__":