Files
Masterprojekt_V3/Export.py
2026-02-05 14:45:27 +01:00

149 lines
6.5 KiB
Python

import csv
from datetime import datetime
import numpy as np
import os
import sympy as sp
import webbrowser
class Export:
"""Hilfsfunktionen zum Exportieren von Ergebnissen und Protokollen.
Die Klasse stellt Methoden zur Verfügung für:
- Export von Matrizen in CSV-Dateien,
- Export von Ausgleichungsergebnissen (Skalare und Matrizen) in CSV-Dateien,
- Erzeugung und Speicherung eines HTML-Protokolls inklusive automatischem Öffnen im Browser.
"""
@staticmethod
def matrix_to_csv(dateiname: str, liste_spaltenbeschriftung: list, liste_zeilenbeschriftung: list, Matrix: np.matrix | sp.Matrix,
beschriftung_kopfzeile: object = "") -> None:
"""Schreibt eine Matrix mit Zeilen- und Spaltenbeschriftungen in eine CSV-Datei.
Die Ausgabe erfolgt mit Semikolon als Trennzeichen. Die Kopfzeile enthält optional eine
zusätzliche Beschriftung sowie Spaltenbeschriftungen.
Zudem werden Zeilenbeschriftungen durchgeführt.
:param dateiname: Pfad zu schreibenden CSV-Datei.
:type dateiname: str
:param liste_spaltenbeschriftung: Liste der Spaltenbeschriftungen.
:type liste_spaltenbeschriftung: list
:param liste_zeilenbeschriftung: Liste der Zeilenbeschriftungen.
:type liste_zeilenbeschriftung: list
:param Matrix: Zu exportierende Matrix.
:type Matrix: np.matrix | sp.Matrix
:param beschriftung_kopfzeile: Optionaler Eintrag in der linken oberen Zelle der Kopfzeile.
:type beschriftung_kopfzeile: object
:return: None
:rtype: None
"""
with open(dateiname, "w", newline="", encoding="utf-8") as csvfile:
writer = csv.writer(csvfile, delimiter=";")
kopfzeile = [beschriftung_kopfzeile]
for spaltenbeschriftung in liste_spaltenbeschriftung:
kopfzeile.append(str(spaltenbeschriftung))
writer.writerow(kopfzeile)
for zeilenbeschriftung, zeile in zip(liste_zeilenbeschriftung, Matrix.tolist()):
zeile_als_text = [zeilenbeschriftung]
for eintrag in zeile:
try:
# Dezimaltrenner von Punkt in Komma ändern, weil Python und Excel andere Konventionen vertreten.
eintrag_text = str(eintrag).replace(".", ",")
try:
eintrag_text = float(eintrag_text)
except:
eintrag_text = eintrag_text
except Exception:
eintrag_text = str(eintrag)
zeile_als_text.append(eintrag_text)
writer.writerow(zeile_als_text)
def speichere_html_protokoll(metadaten: dict, ergebnisse: dict) -> None:
"""Erzeugt ein HTML-Protokoll der Ausgleichungsergebnisse und speichert es als Datei.
Es wird der Unterordner Protokolle angelegt, falls dieser noch nicht existiert.
Das Protokoll wird als HTML-Datei gespeichert und anschließend im Browser geöffnet.
Erwartete Schlüssel in metadaten sind u. a. "projekt", "bearbeiter" und "datum".
Erwartete Schlüssel in ergebnisse sind u. a. "df_globaltest", "df_redundanz",
"df_ellipsen", "df_konfidenzellipsen", "df_koordinaten_geozentrisch_kartesisch"
und "df_koordinaten_utm". Die zugehörigen Werte müssen die Methode to_html bereitstellen.
:param metadaten: Dictionary mit Metadaten zum Protokoll.
:type metadaten: dict
:param ergebnisse: Dictionary mit Ergebnisobjekten (z. B. DataFrames) zur HTML-Ausgabe.
:type ergebnisse: dict
:return: None
:rtype: None
"""
# Pfad für den Ordner erstellen
ordner = "Protokolle"
if not os.path.exists(ordner):
os.makedirs(ordner)
dateiname = f"{ordner}/Protokoll_{metadaten['projekt']}.html"
abs_path = os.path.abspath(dateiname)
# HTML Inhalt zusammenbauen
html_content = f"""
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<style>
body {{ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 40px; line-height: 1.6; color: #333; }}
h1 {{ color: #2c3e50; border-bottom: 2px solid #2c3e50; }}
h3 {{ color: #2980b9; margin-top: 30px; }}
.metadata {{ background: #f9f9f9; padding: 15px; border-radius: 5px; border-left: 5px solid #2980b9; }}
table {{ border-collapse: collapse; width: 100%; margin-top: 10px; }}
th, td {{ text-align: left; padding: 8px; border-bottom: 1px solid #ddd; }}
tr:nth-child(even) {{ background-color: #f2f2f2; }}
th {{ background-color: #2980b9; color: white; }}
.footer {{ margin-top: 50px; font-size: 0.8em; color: #7f8c8d; text-align: center; }}
</style>
<title>Netzprotokoll - {metadaten['projekt']}</title>
</head>
<body>
<h1>Netzprotokoll: {metadaten['projekt']}</h1>
<div class="metadata">
<p><strong>Bearbeiter:</strong> {metadaten['bearbeiter']}</p>
<p><strong>Datum:</strong> {metadaten['datum']}</p>
<p><strong>Ausgleichungsmodus:</strong> Methode der kleinsten Quadrate (L2-Norm)</p>
</div>
<h3>1. Globaltest</h3>
{ergebnisse['df_globaltest'].to_html(index=False)}
<h3>2. Redundanzanteile</h3>
{ergebnisse['df_redundanz'].to_html(index=False)}
<h3>3. Standardellipsen</h3>
{ergebnisse['df_ellipsen'].to_html(index=False)}
<h3>3. Konfidenzellipsen</h3>
{ergebnisse['df_konfidenzellipsen'].to_html(index=False)}
<h3>3. Koordinaten Geozentrisch Kartesisch</h3>
{ergebnisse['df_koordinaten_geozentrisch_kartesisch'].to_html(index=True)}
<h3>3. Koordinaten UTM</h3>
{ergebnisse['df_koordinaten_utm'].to_html(index=True)}
<div class="footer">
Erstellt automatisch am {datetime.now().strftime('%d.%m.%Y um %H:%M:%S')}
</div>
</body>
</html>
"""
# Datei schreiben
with open(dateiname, "w", encoding="utf-8") as f:
f.write(html_content)
print(f"✅ Protokoll wurde gespeichert unter: {abs_path}")
# Datei automatisch im Standard-Browser öffnen
webbrowser.open(f"file://{abs_path}")