diff --git a/debug_adjustment.py b/debug_adjustment.py deleted file mode 100644 index ab37a78..0000000 --- a/debug_adjustment.py +++ /dev/null @@ -1,307 +0,0 @@ -#!/usr/bin/env python3 -""" -Debug-Skript für Netzausgleichung -Prüft Punktevergleich und findet Fehler -""" - -import sys -import math -sys.path.insert(0, '/home/ubuntu/trimble_geodesy') - -from modules.jxl_parser import JXLParser -from modules.network_adjustment import NetworkAdjustment - -def main(): - # Lade JXL - jxl_path = "/home/ubuntu/trimble_geodesy/test_data/Baumschulenstr_93.jxl" - parser = JXLParser() - parser.parse(jxl_path) - - print("=" * 80) - print("DEBUG: NETZAUSGLEICHUNG") - print("=" * 80) - - # Zeige Winkeleinheit - print(f"\n### JXL Einstellungen:") - print(f" Winkeleinheit: {parser.angle_units}") - - # NetworkAdjustment initialisieren - adj = NetworkAdjustment(parser) - - # Beobachtungen extrahieren - adj.extract_observations() - adj.initialize_points() - - # Debug: Zeige Beobachtungen - print(f"\n### Beobachtungen ({len(adj.observations)} total):") - dir_obs = [o for o in adj.observations if o.obs_type == 'direction'] - dist_obs = [o for o in adj.observations if o.obs_type == 'distance'] - zen_obs = [o for o in adj.observations if o.obs_type == 'zenith'] - - print(f" Richtungen: {len(dir_obs)}") - print(f" Strecken: {len(dist_obs)}") - print(f" Zenitwinkel: {len(zen_obs)}") - - print("\n### Beispiel-Beobachtungen (erste 5 Richtungen):") - for obs in dir_obs[:5]: - print(f" {obs.from_station} -> {obs.to_point}: {obs.value:.6f} gon (std: {obs.std_dev:.6f})") - - print("\n### Beispiel-Beobachtungen (erste 5 Strecken):") - for obs in dist_obs[:5]: - print(f" {obs.from_station} -> {obs.to_point}: {obs.value:.4f} m (std: {obs.std_dev:.6f})") - - # Koordinaten vor Ausgleichung speichern - coords_before = {} - for name, pt in adj.points.items(): - coords_before[name] = (pt.x, pt.y, pt.z) - - print(f"\n### Punkte ({len(adj.points)} total):") - for name, pt in sorted(adj.points.items()): - print(f" {name}: X={pt.x:.4f}, Y={pt.y:.4f}, Z={pt.z:.4f}") - - # Festpunkte setzen - ref_points = parser.get_reference_points() - print(f"\n### Referenzpunkte (5xxx): {ref_points}") - - for name in ref_points: - adj.set_fixed_point(name) - - # Falls keine Referenzpunkte, erste Station als Festpunkt - if not adj.fixed_points: - print("WARNUNG: Keine Referenzpunkte gefunden!") - stations = list(parser.stations.values()) - if stations: - first_station = min(stations, key=lambda s: s.timestamp) - adj.set_fixed_point(first_station.name) - print(f" -> Setze {first_station.name} als Festpunkt") - - print(f"\n### Festpunkte: {adj.fixed_points}") - - # Zeige berechnete Orientierungen - print(f"\n### Berechnete Orientierungen pro Station:") - for station_name, orientation in sorted(adj.orientations.items()): - print(f" {station_name}: {orientation:.4f} gon") - - # Konsistenzprüfung - print("\n" + "=" * 80) - print("KONSISTENZPRÜFUNG") - print("=" * 80) - - consistency = adj.check_consistency() - print(f"\n### Ergebnis: {'✅ KONSISTENT' if consistency['consistent'] else '❌ INKONSISTENT'}") - - if not consistency['consistent']: - print("\n### Probleme gefunden:") - for issue in consistency['issues']: - print(f" ⚠️ {issue}") - - print("\n### WICHTIG:") - print(" Die Koordinaten in der JXL-Datei wurden bereits von Trimble Access") - print(" berechnet und sind fertig. Die Beobachtungen (Kreislesungen) sind") - print(" rohe Messwerte, die nicht mit den berechneten Koordinaten konsistent") - print(" verglichen werden können, da die Orientierungen stark variieren.") - print("") - print(" Eine Netzausgleichung mit diesen Daten ist nicht sinnvoll, da sie") - print(" die bereits korrekten Koordinaten verschlechtern würde.") - print("") - print(" Empfehlung: Verwenden Sie die ausgeglichenen Koordinaten aus der JXL") - print(" direkt, ohne weitere Ausgleichung.") - - # Ausgleichung durchführen (nur Residuen, keine Koordinatenänderung) - print("\n### Starte Residuenanalyse (keine Koordinatenänderung)...") - try: - result = adj.adjust(mode="residuals_only") - - print(f"\n### Ergebnis:") - print(f" Konvergiert: {result.converged}") - print(f" Iterationen: {result.iterations}") - print(f" Sigma-0 posteriori: {result.sigma_0_posteriori:.6f}") - print(f" Redundanz: {result.redundancy}") - - # PUNKTEVERGLEICH - print("\n" + "=" * 100) - print("PUNKTEVERGLEICH: VORHER vs. NACHHER") - print("=" * 100) - print(f"{'Punkt':<10} {'X_vorher':>12} {'Y_vorher':>12} {'Z_vorher':>10} | {'X_nachher':>12} {'Y_nachher':>12} {'Z_nachher':>10} | {'ΔX':>10} {'ΔY':>10} {'ΔZ':>10} {'Δ3D':>10}") - print("-" * 120) - - deviations = [] - for name, pt in sorted(adj.points.items()): - x_before, y_before, z_before = coords_before[name] - x_after, y_after, z_after = pt.x, pt.y, pt.z - - dx = x_after - x_before - dy = y_after - y_before - dz = z_after - z_before - d3d = math.sqrt(dx**2 + dy**2 + dz**2) - - deviations.append((name, dx, dy, dz, d3d, pt.is_fixed)) - - fixed_marker = "*" if pt.is_fixed else " " - print(f"{name:<10}{fixed_marker} {x_before:>12.4f} {y_before:>12.4f} {z_before:>10.4f} | " - f"{x_after:>12.4f} {y_after:>12.4f} {z_after:>10.4f} | " - f"{dx:>10.4f} {dy:>10.4f} {dz:>10.4f} {d3d:>10.4f}") - - # PLAUSIBILITÄTSPRÜFUNG - print("\n" + "=" * 80) - print("PLAUSIBILITÄTSPRÜFUNG") - print("=" * 80) - - # Sortiert nach größter Abweichung - deviations_sorted = sorted(deviations, key=lambda x: x[4], reverse=True) - - # Warnungen - critical_errors = [] - warnings = [] - for name, dx, dy, dz, d3d, is_fixed in deviations_sorted: - if not is_fixed: - if d3d > 1.0: - critical_errors.append((name, d3d)) - elif d3d > 0.1: - warnings.append((name, d3d)) - - if critical_errors: - print("\n🚨 KRITISCHE FEHLER (Abweichung > 1m):") - for name, d3d in critical_errors: - print(f" ❌ {name}: {d3d:.4f} m") - - if warnings: - print("\n⚠️ WARNUNGEN (Abweichung > 10cm):") - for name, d3d in warnings: - print(f" ⚠ {name}: {d3d:.4f} m") - - # Statistik - non_fixed_deviations = [d for d in deviations if not d[5]] - if non_fixed_deviations: - d3d_values = [d[4] for d in non_fixed_deviations] - dx_values = [abs(d[1]) for d in non_fixed_deviations] - dy_values = [abs(d[2]) for d in non_fixed_deviations] - - print("\n### Statistik (nur Neupunkte):") - print(f" Anzahl Punkte: {len(non_fixed_deviations)}") - print(f" Min Δ3D: {min(d3d_values):.6f} m") - print(f" Max Δ3D: {max(d3d_values):.6f} m") - print(f" Mittel Δ3D: {sum(d3d_values)/len(d3d_values):.6f} m") - print(f" Max |ΔX|: {max(dx_values):.6f} m") - print(f" Max |ΔY|: {max(dy_values):.6f} m") - - if not critical_errors and not warnings: - print("\n✅ Alle Koordinaten unverändert (wie erwartet bei residuals_only)") - - # RESIDUEN-ANALYSE - print("\n" + "=" * 80) - print("RESIDUENANALYSE") - print("=" * 80) - - dir_obs = [o for o in adj.observations if o.obs_type == 'direction'] - dist_obs = [o for o in adj.observations if o.obs_type == 'distance'] - - dir_residuals = [o.residual * 1000 for o in dir_obs] # in mgon - dist_residuals = [o.residual * 1000 for o in dist_obs] # in mm - - if dir_residuals: - print(f"\n### Richtungsresiduen (in mgon):") - print(f" Anzahl: {len(dir_residuals)}") - print(f" Min: {min(dir_residuals):.2f} mgon") - print(f" Max: {max(dir_residuals):.2f} mgon") - print(f" RMSE: {math.sqrt(sum(r**2 for r in dir_residuals)/len(dir_residuals)):.2f} mgon") - - if dist_residuals: - print(f"\n### Streckenresiduen (in mm):") - print(f" Anzahl: {len(dist_residuals)}") - print(f" Min: {min(dist_residuals):.2f} mm") - print(f" Max: {max(dist_residuals):.2f} mm") - print(f" RMSE: {math.sqrt(sum(r**2 for r in dist_residuals)/len(dist_residuals)):.2f} mm") - - # Zeige größte Residuen - print(f"\n### Größte Richtungsresiduen:") - sorted_dir = sorted(dir_obs, key=lambda x: abs(x.residual), reverse=True)[:5] - for obs in sorted_dir: - print(f" {obs.from_station} -> {obs.to_point}: {obs.residual*1000:.2f} mgon") - - print(f"\n### Größte Streckenresiduen:") - sorted_dist = sorted(dist_obs, key=lambda x: abs(x.residual), reverse=True)[:5] - for obs in sorted_dist: - print(f" {obs.from_station} -> {obs.to_point}: {obs.residual*1000:.2f} mm") - - # Qualitätsbewertung - rmse_dir = math.sqrt(sum(r**2 for r in dir_residuals)/len(dir_residuals)) if dir_residuals else 0 - rmse_dist = math.sqrt(sum(r**2 for r in dist_residuals)/len(dist_residuals)) if dist_residuals else 0 - - print("\n### Qualitätsbewertung:") - if rmse_dir < 10: - print(f" ✅ Richtungen: SEHR GUT (RMSE < 10 mgon)") - elif rmse_dir < 50: - print(f" ✅ Richtungen: GUT (RMSE < 50 mgon)") - elif rmse_dir < 100: - print(f" ⚠️ Richtungen: AKZEPTABEL (RMSE < 100 mgon)") - else: - print(f" ❌ Richtungen: SCHLECHT (RMSE = {rmse_dir:.2f} mgon)") - - if rmse_dist < 5: - print(f" ✅ Strecken: SEHR GUT (RMSE < 5 mm)") - elif rmse_dist < 20: - print(f" ✅ Strecken: GUT (RMSE < 20 mm)") - elif rmse_dist < 50: - print(f" ⚠️ Strecken: AKZEPTABEL (RMSE < 50 mm)") - else: - print(f" ❌ Strecken: SCHLECHT (RMSE = {rmse_dist:.2f} mm)") - - # Prüfe ob Problem besteht - max_d3d = max(d[4] for d in non_fixed_deviations) if non_fixed_deviations else 0 - if max_d3d > 1.0: - print("\n" + "=" * 80) - print("🔍 FEHLERANALYSE") - print("=" * 80) - - # Prüfe berechnete vs. beobachtete Richtungen - print("\n### Prüfung Richtungsbeobachtungen:") - for obs in dir_obs[:3]: - from_pt = adj.points.get(obs.from_station) - to_pt = adj.points.get(obs.to_point) - if from_pt and to_pt: - dx = to_pt.x - from_pt.x - dy = to_pt.y - from_pt.y - # Berechne Azimut in Gon (aus X,Y) - azimuth_calc = math.atan2(dx, dy) * 200.0 / math.pi - if azimuth_calc < 0: - azimuth_calc += 400.0 - - diff = obs.value - azimuth_calc - while diff > 200: - diff -= 400 - while diff < -200: - diff += 400 - - print(f" {obs.from_station} -> {obs.to_point}:") - print(f" Beobachtet: {obs.value:.6f} gon") - print(f" Berechnet: {azimuth_calc:.6f} gon") - print(f" Differenz: {diff:.6f} gon ({diff*10000:.2f} mgon)") - - # Prüfe berechnete vs. beobachtete Strecken - print("\n### Prüfung Streckenbeobachtungen:") - for obs in dist_obs[:3]: - from_pt = adj.points.get(obs.from_station) - to_pt = adj.points.get(obs.to_point) - if from_pt and to_pt: - dx = to_pt.x - from_pt.x - dy = to_pt.y - from_pt.y - dz = to_pt.z - from_pt.z - dist_calc_3d = math.sqrt(dx**2 + dy**2 + dz**2) - dist_calc_2d = math.sqrt(dx**2 + dy**2) - - diff_3d = obs.value - dist_calc_3d - diff_2d = obs.value - dist_calc_2d - - print(f" {obs.from_station} -> {obs.to_point}:") - print(f" Beobachtet: {obs.value:.6f} m") - print(f" Berechnet 3D: {dist_calc_3d:.6f} m (Diff: {diff_3d*1000:.2f} mm)") - print(f" Berechnet 2D: {dist_calc_2d:.6f} m (Diff: {diff_2d*1000:.2f} mm)") - - except Exception as e: - print(f"FEHLER: {e}") - import traceback - traceback.print_exc() - -if __name__ == "__main__": - main()