Merge remote-tracking branch 'origin/main'

This commit is contained in:
2025-12-09 16:03:41 +01:00
8 changed files with 2495 additions and 1248 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -6,15 +6,17 @@
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2025-12-08T16:59:58.933024Z",
"start_time": "2025-12-08T16:59:58.578335Z"
"end_time": "2025-12-09T12:25:40.573167Z",
"start_time": "2025-12-09T12:25:40.219840Z"
}
},
"source": [
"# Hier werden alle verwendeten Pythonmodule importiert\n",
"import Datenbank\n",
"import Import\n",
"import importlib"
"import importlib\n",
"import Koordinatentransformationen\n",
"import sqlite3"
],
"outputs": [],
"execution_count": 1
@@ -22,8 +24,8 @@
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-08T17:00:01.134916Z",
"start_time": "2025-12-08T17:00:01.110846Z"
"end_time": "2025-12-09T12:25:40.603148Z",
"start_time": "2025-12-09T12:25:40.579387Z"
}
},
"cell_type": "code",
@@ -44,14 +46,14 @@
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-08T17:00:02.698814Z",
"start_time": "2025-12-08T17:00:02.678346Z"
"end_time": "2025-12-09T12:25:40.629729Z",
"start_time": "2025-12-09T12:25:40.608515Z"
}
},
"cell_type": "code",
"source": [
"# Import der Koordinatendatei(en) vom Tachymeter\n",
"pfad_datei = r\"Daten\\campusnetz_koordinaten_25_11.csv\"\n",
"pfad_datei = r\"Daten\\campsnetz_final_koordinaten.csv\"\n",
"imp.import_koordinaten_lh_tachymeter(pfad_datei)"
],
"id": "d3bce3991a8962dc",
@@ -69,8 +71,8 @@
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-08T17:00:13.157273Z",
"start_time": "2025-12-08T17:00:13.147245Z"
"end_time": "2025-12-09T12:25:40.645668Z",
"start_time": "2025-12-09T12:25:40.635523Z"
}
},
"cell_type": "code",
@@ -86,170 +88,676 @@
"name": "stdout",
"output_type": "stream",
"text": [
"[{'10009': Matrix([\n",
"{'10009': Matrix([\n",
"[1000.0],\n",
"[2000.0],\n",
"[ 100.0]])}, {'10006': Matrix([\n",
"[ 100.0]]), '10006': Matrix([\n",
"[ 1000.0],\n",
"[2032.6863],\n",
"[ 99.5825]])}, {'10010': Matrix([\n",
"[ 99.5825]]), '10010': Matrix([\n",
"[1011.8143],\n",
"[1973.3252],\n",
"[ 99.9259]])}, {'10018': Matrix([\n",
"[ 99.9259]]), '10018': Matrix([\n",
"[1008.5759],\n",
"[ 1942.762],\n",
"[ 100.2553]])}, {'10008': Matrix([\n",
"[ 100.2553]]), '10008': Matrix([\n",
"[979.7022],\n",
"[1991.401],\n",
"[ 99.732]])}, {'10005': Matrix([\n",
"[ 99.732]]), '10005': Matrix([\n",
"[ 966.5154],\n",
"[2014.6496],\n",
"[ 99.72]])}, {'10003': Matrix([\n",
"[ 99.72]]), '10003': Matrix([\n",
"[ 908.4312],\n",
"[1996.1248],\n",
"[ 99.7403]])}, {'10004': Matrix([\n",
"[ 99.7403]]), '10004': Matrix([\n",
"[ 954.1536],\n",
"[2021.6822],\n",
"[ 99.4916]])}, {'10007': Matrix([\n",
"[ 99.4916]]), '10007': Matrix([\n",
"[ 921.7481],\n",
"[1973.6201],\n",
"[ 99.9176]])}, {'10001': Matrix([\n",
"[ 99.9176]]), '10001': Matrix([\n",
"[ 833.9439],\n",
"[1978.3737],\n",
"[ 99.8946]])}, {'10002': Matrix([\n",
"[ 99.8946]]), '10002': Matrix([\n",
"[ 875.9684],\n",
"[1998.5174],\n",
"[ 99.5867]])}, {'100016': Matrix([\n",
"[ 99.5867]]), '100016': Matrix([\n",
"[ 928.2783],\n",
"[1944.0082],\n",
"[ 100.0459]])}, {'10011': Matrix([\n",
"[ 100.0459]]), '10011': Matrix([\n",
"[ 908.4308],\n",
"[1996.1277],\n",
"[ 99.7822]])}, {'10011a': Matrix([\n",
"[ 99.7822]]), '10011a': Matrix([\n",
"[844.9567],\n",
"[1891.157],\n",
"[ 99.8117]])}, {'10026': Matrix([\n",
"[ 99.8117]]), '10026': Matrix([\n",
"[1020.0059],\n",
"[1913.8703],\n",
"[ 100.3059]])}, {'10027': Matrix([\n",
"[ 100.3059]]), '10027': Matrix([\n",
"[1016.9451],\n",
"[1866.2914],\n",
"[ 100.3251]])}, {'10043': Matrix([\n",
"[ 100.3251]]), '10043': Matrix([\n",
"[1031.2077],\n",
"[1822.4739],\n",
"[ 100.3035]])}, {'10044': Matrix([\n",
"[ 100.3035]]), '10044': Matrix([\n",
"[ 1025.976],\n",
"[1782.4835],\n",
"[ 100.5461]])}, {'10021': Matrix([\n",
"[ 100.5461]]), '10021': Matrix([\n",
"[ 992.7607],\n",
"[1904.8854],\n",
"[ 100.3533]])}, {'10020': Matrix([\n",
"[ 100.3533]]), '10020': Matrix([\n",
"[ 984.6187],\n",
"[1903.3601],\n",
"[ 100.3423]])}, {'10024': Matrix([\n",
"[ 100.3423]]), '10024': Matrix([\n",
"[ 997.4831],\n",
"[1881.7862],\n",
"[ 100.3032]])}, {'10025': Matrix([\n",
"[ 100.3032]]), '10025': Matrix([\n",
"[996.3241],\n",
"[1866.844],\n",
"[100.4102]])}, {'10022': Matrix([\n",
"[100.4102]]), '10022': Matrix([\n",
"[990.0679],\n",
"[1896.536],\n",
"[100.2194]])}, {'10023': Matrix([\n",
"[100.2194]]), '10023': Matrix([\n",
"[ 987.3223],\n",
"[1889.8762],\n",
"[ 100.343]])}, {'10019': Matrix([\n",
"[ 100.343]]), '10019': Matrix([\n",
"[ 962.6387],\n",
"[1902.3565],\n",
"[ 99.9772]])}, {'10033': Matrix([\n",
"[ 99.9772]]), '10033': Matrix([\n",
"[ 964.0191],\n",
"[1860.8023],\n",
"[ 99.8551]])}, {'10017': Matrix([\n",
"[ 99.8551]]), '10017': Matrix([\n",
"[ 931.6761],\n",
"[1900.9945],\n",
"[ 99.9572]])}, {'10052': Matrix([\n",
"[ 99.9572]]), '10052': Matrix([\n",
"[ 1037.875],\n",
"[1757.2999],\n",
"[ 100.2737]])}, {'10042': Matrix([\n",
"[ 100.2737]]), '10042': Matrix([\n",
"[1017.3489],\n",
"[1803.0742],\n",
"[ 100.3441]])}, {'10053': Matrix([\n",
"[ 100.3441]]), '10053': Matrix([\n",
"[1033.3758],\n",
"[1723.4258],\n",
"[ 100.2774]])}, {'10037': Matrix([\n",
"[ 100.2774]]), '10037': Matrix([\n",
"[ 966.2253],\n",
"[1774.2051],\n",
"[ 99.9957]])}, {'10040': Matrix([\n",
"[ 99.9957]]), '10040': Matrix([\n",
"[ 990.8832],\n",
"[1780.9678],\n",
"[ 100.1677]])}, {'10041': Matrix([\n",
"[ 100.1677]]), '10041': Matrix([\n",
"[993.2769],\n",
"[1812.031],\n",
"[100.4749]])}, {'10038': Matrix([\n",
"[100.4749]]), '10038': Matrix([\n",
"[ 958.1899],\n",
"[1804.7135],\n",
"[ 100.0741]])}, {'10051': Matrix([\n",
"[ 100.0741]]), '10051': Matrix([\n",
"[1008.9811],\n",
"[1750.1838],\n",
"[ 100.288]])}, {'10036': Matrix([\n",
"[ 100.288]]), '10036': Matrix([\n",
"[ 948.6403],\n",
"[1763.5807],\n",
"[ 100.0063]])}, {'10035': Matrix([\n",
"[ 100.0063]]), '10035': Matrix([\n",
"[ 910.1265],\n",
"[1768.0099],\n",
"[ 100.0781]])}, {'10039': Matrix([\n",
"[ 100.0781]]), '10039': Matrix([\n",
"[ 960.3884],\n",
"[1820.0543],\n",
"[ 100.0983]])}, {'10059': Matrix([\n",
"[ 100.0983]]), '10059': Matrix([\n",
"[1049.2587],\n",
"[1662.5451],\n",
"[ 100.0148]])}, {'10050': Matrix([\n",
"[ 100.0148]]), '10050': Matrix([\n",
"[1010.0246],\n",
"[1726.2445],\n",
"[ 100.1493]])}, {'10049': Matrix([\n",
"[ 100.1493]]), '10049': Matrix([\n",
"[ 984.7667],\n",
"[1714.5709],\n",
"[ 100.0101]])}, {'100': Matrix([\n",
"[ 100.0101]]), '100': Matrix([\n",
"[ 957.3912],\n",
"[1716.2864],\n",
"[ 99.7777]])}, {'10013': Matrix([\n",
"[ 99.7777]]), '10013': Matrix([\n",
"[900.9076],\n",
"[1902.873],\n",
"[ 99.7911]])}, {'10028': Matrix([\n",
"[ 99.7911]]), '10028': Matrix([\n",
"[ 853.9608],\n",
"[1815.7417],\n",
"[ 99.7793]])}, {'10012': Matrix([\n",
"[ 99.7793]]), '10012': Matrix([\n",
"[ 895.3032],\n",
"[1924.1523],\n",
"[ 99.8758]])}, {'10014': Matrix([\n",
"[ 99.8758]]), '10014': Matrix([\n",
"[ 913.9706],\n",
"[1918.7731],\n",
"[ 99.8872]])}, {'10031': Matrix([\n",
"[ 99.8872]]), '10031': Matrix([\n",
"[ 937.1557],\n",
"[1855.2805],\n",
"[ 99.8479]])}, {'10015': Matrix([\n",
"[ 99.8479]]), '10015': Matrix([\n",
"[ 912.5157],\n",
"[1937.6471],\n",
"[ 99.9834]])}, {'10032': Matrix([\n",
"[ 99.9834]]), '10032': Matrix([\n",
"[ 954.6732],\n",
"[1845.9356],\n",
"[ 99.724]])}, {'10030': Matrix([\n",
"[ 99.724]]), '10030': Matrix([\n",
"[ 908.4749],\n",
"[1828.8008],\n",
"[ 99.5581]])}, {'10029': Matrix([\n",
"[ 99.5581]]), '10029': Matrix([\n",
"[ 909.3343],\n",
"[1814.8767],\n",
"[ 99.5486]])}, {'10034': Matrix([\n",
"[ 99.5486]]), '10034': Matrix([\n",
"[ 860.2357],\n",
"[1758.9282],\n",
"[ 99.737]])}, {'10045': Matrix([\n",
"[ 99.737]]), '10045': Matrix([\n",
"[867.2324],\n",
"[1705.063],\n",
"[ 99.7214]])}]\n"
"[ 99.7214]]), '10049a': Matrix([\n",
"[ 985.2561],\n",
"[1715.2109],\n",
"[ 99.9965]]), '10048': Matrix([\n",
"[ 957.3889],\n",
"[1716.2949],\n",
"[ 99.7212]]), '10047': Matrix([\n",
"[ 929.5334],\n",
"[1712.6429],\n",
"[ 99.6076]]), '10046': Matrix([\n",
"[ 910.663],\n",
"[1716.0969],\n",
"[ 99.5459]]), '10057': Matrix([\n",
"[969.6876],\n",
"[1655.597],\n",
"[ 99.7039]]), '10055': Matrix([\n",
"[ 922.4731],\n",
"[1647.7452],\n",
"[ 99.4658]]), '10054': Matrix([\n",
"[ 860.4481],\n",
"[1636.6722],\n",
"[ 99.7093]]), '10058': Matrix([\n",
"[1013.2592],\n",
"[1646.6356],\n",
"[ 99.8513]]), '10056': Matrix([\n",
"[ 939.9763],\n",
"[1636.4179],\n",
"[ 99.4027]])}\n"
]
}
],
"execution_count": 4
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-09T12:25:40.666696Z",
"start_time": "2025-12-09T12:25:40.654193Z"
}
},
"cell_type": "code",
"source": [
"importlib.reload(Datenbank)\n",
"db_zugriff = Datenbank.Datenbankzugriff(pfad_datenbank)\n",
"# Transformationen in ETRS89 / DREF91 Realisierung 2025\n",
"print(db_zugriff.get_koordinaten(\"naeherung_us\"))"
],
"id": "3989b7b41874c16a",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{}\n"
]
}
],
"execution_count": 5
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-09T12:25:40.711147Z",
"start_time": "2025-12-09T12:25:40.686969Z"
}
},
"cell_type": "code",
"source": [
"# ToDo: Sobald GNSS vorliegend Koordinaten im ETRS89 / DREF 91 (2025) daraus berechnen!\n",
"liste_koordinaten_naeherung_us_alt = {\n",
" 10001: (3794874.98408291, 546741.751930012, 5079995.3838),\n",
" 10002: (3794842.53340714, 546726.907150697, 5080039.8778),\n",
" 10008: (3794757.41294192, 546742.822339098, 5080107.3198),\n",
" 10012: (3794827.11937161, 546801.412652168, 5080028.5852),\n",
" 10026: (3794727.06042449, 546823.571170112, 5080134.2029),\n",
" 10028: (3794862.91900719, 546904.943464041, 5079920.8994),\n",
" 10037: (3794774.14751515, 546955.423068316, 5079960.9426),\n",
" 10044: (3794725.78597473, 546954.557211544, 5080009.9234),\n",
" 10054: (3794852.07416848, 547094.399826613, 5079715.1737),\n",
" 10059: (3794710.34348443, 547075.630380075, 5080119.6491),\n",
"}\n",
"\n",
"liste_koordinaten_naeherung_us_V2 = {\n",
" 10001: (3794874.984, 546741.752, 5080029.990),\n",
" 10002: (3794842.533, 546726.907, 5080071.133),\n",
" 10008: (3794757.413, 546742.822, 5080135.400),\n",
" 10012: (3794827.119, 546801.413, 5080065.404),\n",
" 10026: (3794727.060, 546823.571, 5080179.951),\n",
" 10028: (3794862.919, 546904.943, 5079963.214),\n",
" 10037: (3794774.148, 546955.423, 5080040.520),\n",
" 10044: (3794725.786, 546954.557, 5080084.411),\n",
" 10054: (3794852.074, 547094.400, 5079771.845),\n",
" 10059: (3794710.343, 547075.630, 5080153.653),\n",
"}\n",
"\n",
"liste_koordinaten_naeherung_us = {\n",
" 10001: (3794874.984, 546741.752, 5080029.990),\n",
" 10002: (3794842.533, 546726.907, 5080071.133),\n",
" 10037: (3794774.148, 546955.423, 5080040.520),\n",
" 10044: (3794725.786, 546954.557, 5080084.411),\n",
"}\n",
"\n",
"\n",
"con = sqlite3.connect(pfad_datenbank)\n",
"cursor = con.cursor()\n",
"sql = \"\"\"\n",
"UPDATE Netzpunkte\n",
"SET naeherungx_us = ?, naeherungy_us = ?, naeherungz_us = ?\n",
"WHERE punktnummer = ?\n",
"\"\"\"\n",
"for punktnummer, (x, y, z) in liste_koordinaten_naeherung_us.items():\n",
" cursor.execute(sql, (x, y, z, punktnummer))\n",
"con.commit()\n",
"cursor.close()\n",
"con.close()"
],
"id": "f64d9c01318b40f1",
"outputs": [],
"execution_count": 6
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-09T12:38:18.913365Z",
"start_time": "2025-12-09T12:38:17.077549Z"
}
},
"cell_type": "code",
"source": [
"# ToDo: Sobald GNSS-Daten vorliegen und die Berechnungen richtig sind, aufräumen!!!\n",
"\n",
"importlib.reload(Koordinatentransformationen)\n",
"trafos = Koordinatentransformationen.Transformationen(pfad_datenbank)\n",
"\n",
"\n",
"import numpy as np\n",
"\n",
"import itertools\n",
"import numpy as np\n",
"import sympy as sp\n",
"\n",
"db = Datenbank.Datenbankzugriff(pfad_datenbank)\n",
"dict_ausgangssystem = db.get_koordinaten(\"naeherung_lh\", \"Dict\")\n",
"dict_zielsystem = db.get_koordinaten(\"naeherung_us\", \"Dict\")\n",
"\n",
"gemeinsame_punktnummern = sorted(set(dict_ausgangssystem.keys()) & set(dict_zielsystem.keys()))\n",
"anzahl_gemeinsame_punkte = len(gemeinsame_punktnummern)\n",
"\n",
"liste_punkte_ausgangssystem = [dict_ausgangssystem[i] for i in gemeinsame_punktnummern]\n",
"liste_punkte_zielsystem = [dict_zielsystem[i] for i in gemeinsame_punktnummern]\n",
"\n",
"def dist(a, b):\n",
" return float((a - b).norm())\n",
"\n",
"print(\"d(p2,p1)=\", dist(liste_punkte_ausgangssystem[1], liste_punkte_ausgangssystem[0]))\n",
"print(\"d(P2,P1)=\", dist(liste_punkte_zielsystem[1], liste_punkte_zielsystem[0]))\n",
"print(\"m0 ~\", dist(liste_punkte_zielsystem[1], liste_punkte_zielsystem[0]) /\n",
" dist(liste_punkte_ausgangssystem[1], liste_punkte_ausgangssystem[0]))\n",
"\n",
"\n",
"def dist(a, b):\n",
" return float((a - b).norm())\n",
"\n",
"ratios = []\n",
"pairs = list(itertools.combinations(range(len(liste_punkte_ausgangssystem)), 2))\n",
"\n",
"for i, j in pairs:\n",
" d_loc = dist(liste_punkte_ausgangssystem[i], liste_punkte_ausgangssystem[j])\n",
" d_ecef = dist(liste_punkte_zielsystem[i], liste_punkte_zielsystem[j])\n",
" if d_loc > 1e-6:\n",
" ratios.append(d_ecef / d_loc)\n",
"\n",
"print(\"Anzahl Ratios:\", len(ratios))\n",
"print(\"min/mean/max:\", min(ratios), sum(ratios)/len(ratios), max(ratios))\n",
"print(\"std:\", float(np.std(ratios)))\n",
"\n",
"S_loc = sum(liste_punkte_ausgangssystem, sp.Matrix([0,0,0])) / anzahl_gemeinsame_punkte\n",
"S_ecef = sum(liste_punkte_zielsystem, sp.Matrix([0,0,0])) / anzahl_gemeinsame_punkte\n",
"\n",
"print(\"S_loc:\", S_loc)\n",
"print(\"S_ecef:\", S_ecef)\n",
"print(\"Delta:\", (S_ecef - S_loc).evalf(6))\n",
"\n",
"\n",
"def dist(a, b):\n",
" return float((a - b).norm())\n",
"\n",
"n = len(liste_punkte_ausgangssystem)\n",
"\n",
"scores = []\n",
"for i in range(n):\n",
" d_loc = []\n",
" d_ecef = []\n",
" for j in range(n):\n",
" if i == j:\n",
" continue\n",
" d_loc.append(dist(liste_punkte_ausgangssystem[i], liste_punkte_ausgangssystem[j]))\n",
" d_ecef.append(dist(liste_punkte_zielsystem[i], liste_punkte_zielsystem[j]))\n",
"\n",
" d_loc = np.array(d_loc)\n",
" d_ecef = np.array(d_ecef)\n",
"\n",
" # Verhältnisvektor; robust gegen Nullschutz\n",
" r = d_ecef / np.where(d_loc == 0, np.nan, d_loc)\n",
"\n",
" # Streuung der Ratios für Punkt i\n",
" score = np.nanstd(r)\n",
" scores.append(score)\n",
"\n",
"for pn, sc in sorted(zip(gemeinsame_punktnummern, scores), key=lambda x: -x[1]):\n",
" print(pn, round(sc, 4))\n",
"\n",
"\n",
"\n",
"transformationsparameter = trafos.Helmerttransformation_Euler_Transformationsparameter_berechne()"
],
"id": "21d60465e432c649",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"d(p2,p1)= 46.60388451996242\n",
"d(P2,P1)= 54.462720048072995\n",
"m0 ~ 1.1686304823956102\n",
"Anzahl Ratios: 6\n",
"min/mean/max: 0.9679784506116116 1.0266943302085056 1.1686304823956102\n",
"std: 0.07473161831852519\n",
"S_loc: Matrix([[925.528400000000], [1883.39492500000], [100.005775000000]])\n",
"S_ecef: Matrix([[3794804.36275000], [546844.659750000], [5080056.51350000]])\n",
"Delta: Matrix([[3.79388e+6], [544961.], [5.07996e+6]])\n",
"10001 0.0936\n",
"10002 0.0873\n",
"10044 0.0527\n",
"10037 0.0477\n",
"Anzahl gemeinsame Punkte: 4\n",
"\n",
"Erste Zielpunkte:\n",
"10001 [3794874.984, 546741.752, 5080029.99]\n",
"10002 [3794842.533, 546726.907, 5080071.133]\n",
"10037 [3794774.148, 546955.423, 5080040.52]\n",
"10044 [3794725.786, 546954.557, 5080084.411]\n",
"\n",
"Erste Ausgangspunkte:\n",
"10001 [833.9439, 1978.3737, 99.8946]\n",
"10002 [875.9684, 1998.5174, 99.5867]\n",
"10037 [966.2253, 1774.2051, 99.9957]\n",
"10044 [1025.976, 1782.4835, 100.5461]\n",
"min/mean/max: 0.9679784506116116 1.0266943302085056 1.1686304823956102\n",
"R ist Orthonormal!\n",
"Iteration Nr.1 abgeschlossen\n",
"Matrix([[-85.7], [-61.5], [188.], [-0.246], [-0.821], [0.00489], [0.406]])\n",
"Iteration Nr.2 abgeschlossen\n",
"Matrix([[241.], [-94.3], [-151.], [0.191], [-0.153], [-0.109], [0.120]])\n",
"Iteration Nr.3 abgeschlossen\n",
"Matrix([[5.71], [5.03], [0.723], [0.00670], [0.0401], [0.0180], [-0.0355]])\n",
"Iteration Nr.4 abgeschlossen\n",
"Matrix([[-2.83], [-1.48], [-2.88], [0.000657], [-0.00186], [0.00135], [0.00102]])\n",
"Iteration Nr.5 abgeschlossen\n",
"Matrix([[0.441], [0.196], [0.417], [6.90e-8], [0.000310], [-0.000257], [-0.000169]])\n",
"Iteration Nr.6 abgeschlossen\n",
"Matrix([[-0.0781], [-0.0348], [-0.0729], [1.91e-9], [-5.48e-5], [4.49e-5], [3.00e-5]])\n",
"Iteration Nr.7 abgeschlossen\n",
"Matrix([[0.0137], [0.00611], [0.0128], [5.92e-11], [9.61e-6], [-7.89e-6], [-5.25e-6]])\n",
"Iteration Nr.8 abgeschlossen\n",
"Matrix([[-0.00241], [-0.00107], [-0.00225], [1.35e-12], [-1.69e-6], [1.39e-6], [9.23e-7]])\n",
"Iteration Nr.9 abgeschlossen\n",
"Matrix([[0.000423], [0.000188], [0.000395], [-4.72e-13], [2.96e-7], [-2.43e-7], [-1.62e-7]])\n",
"Iteration Nr.10 abgeschlossen\n",
"Matrix([[-7.42e-5], [-3.31e-5], [-6.95e-5], [1.10e-12], [-5.21e-8], [4.27e-8], [2.85e-8]])\n",
"Iteration Nr.11 abgeschlossen\n",
"Matrix([[1.30e-5], [5.82e-6], [1.22e-5], [-3.48e-13], [9.15e-9], [-7.51e-9], [-5.00e-9]])\n",
"Matrix([[3.79e+6], [5.47e+5], [5.08e+6], [3.79e+6], [5.47e+5], [5.08e+6], [3.79e+6], [5.47e+5], [5.08e+6], [3.79e+6], [5.47e+5], [5.08e+6]])\n",
"Matrix([[3.79e+6], [5.46e+5], [5.08e+6], [3.79e+6], [5.46e+5], [5.08e+6], [3.79e+6], [5.47e+5], [5.08e+6], [3.79e+6], [5.47e+5], [5.08e+6]])\n",
"x = Matrix([[3.80e+6], [5.48e+5], [5.08e+6], [0.979], [-0.481], [0.677], [3.42]])\n",
"\n",
"l_berechnet_final:\n",
"10001: 3794874.637, 546738.682, 5080033.793\n",
"10002: 3794844.297, 546729.060, 5080066.484\n",
"10037: 3794770.848, 546952.857, 5080042.910\n",
"10044: 3794727.668, 546958.039, 5080082.867\n",
"Streckendifferenzen:\n",
"[4.899982, 5.418896, 4.814927, 4.248968]\n",
"\n",
"Differenz Schwerpunkt (Vektor):\n",
"Matrix([[-4.66e-10], [-2.91e-11], [-4.66e-10]])\n",
"Betrag der Schwerpunkt-Differenz:\n",
"0.000m\n"
]
}
],
"execution_count": 10
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-09T13:21:57.869927Z",
"start_time": "2025-12-09T13:21:57.831927Z"
}
},
"cell_type": "code",
"source": [
"importlib.reload(Koordinatentransformationen)\n",
"trafos = Koordinatentransformationen.Transformationen(pfad_datenbank)\n",
"\n",
"koordinaten_transformiert = trafos.Helmerttransformation(transformationsparameter)\n",
"print(koordinaten_transformiert)"
],
"id": "df0dcccb73299fcf",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'100': Matrix([\n",
"[3794775.24129598],\n",
"[547003.784566026],\n",
"[5080016.88582709]]), '100016': Matrix([\n",
"[3794804.40667566],\n",
"[546789.942078133],\n",
"[5080079.63649543]]), '10003': Matrix([\n",
"[3794820.51175889],\n",
"[546738.121545569],\n",
"[5080085.66027136]]), '10004': Matrix([\n",
"[3794787.68039096],\n",
"[546724.355539902],\n",
"[5080122.57197924]]), '10005': Matrix([\n",
"[3794778.52744143],\n",
"[546733.440239574],\n",
"[5080127.82709672]]), '10006': Matrix([\n",
"[3794754.48961774],\n",
"[546723.992131817],\n",
"[ 5080154.6491784]]), '10007': Matrix([\n",
"[ 3794810.10603],\n",
"[546761.510609237],\n",
"[ 5080086.0020765]]), '10008': Matrix([\n",
"[3794768.08506589],\n",
"[546757.433496855],\n",
"[ 5080127.7145515]]), '10009': Matrix([\n",
"[3794753.66298807],\n",
"[546753.936763795],\n",
"[ 5080143.3866772]]), '10010': Matrix([\n",
"[3794744.05628981],\n",
"[546780.742811981],\n",
"[ 5080141.1636738]]), '10011': Matrix([\n",
"[3794820.53929209],\n",
"[546738.130781189],\n",
"[ 5080085.6893844]]), '10011a': Matrix([\n",
"[3794863.58049222],\n",
"[546820.559672293],\n",
"[5080009.68904121]]), '10012': Matrix([\n",
"[3794827.81056398],\n",
"[ 546801.06957277],\n",
"[ 5080052.2764653]]), '10013': Matrix([\n",
"[3794822.93179095],\n",
"[ 546821.6420314],\n",
"[5080048.14190298]]), '10014': Matrix([\n",
"[3794813.94866435],\n",
"[546809.911071387],\n",
"[5080061.83762516]]), '10015': Matrix([\n",
"[3794815.71134214],\n",
"[ 546792.41022388],\n",
"[5080067.67633712]]), '10017': Matrix([\n",
"[ 3794800.4139096],\n",
"[546829.880936662],\n",
"[5080066.46875977]]), '10018': Matrix([\n",
"[3794745.61855632],\n",
"[546808.043262064],\n",
"[5080128.60455588]]), '10019': Matrix([\n",
"[3794777.76781701],\n",
"[546835.162107796],\n",
"[5080085.96045632]]), '10020': Matrix([\n",
"[3794761.92015664],\n",
"[546838.977847251],\n",
"[5080100.04765691]]), '10021': Matrix([\n",
"[3794756.00797839],\n",
"[546839.303246531],\n",
"[5080105.58935921]]), '10022': Matrix([\n",
"[3794757.61562001],\n",
"[546846.316729031],\n",
"[5080100.89762826]]), '10023': Matrix([\n",
"[3794759.48549621],\n",
"[546851.850918009],\n",
"[5080096.94440005]]), '10024': Matrix([\n",
"[3794751.73730327],\n",
"[546861.360519194],\n",
"[ 5080100.294253]]), '10025': Matrix([\n",
"[3794752.15498749],\n",
"[546874.781453645],\n",
"[5080094.37790759]]), '10026': Matrix([\n",
"[3794736.30003562],\n",
"[546836.826883513],\n",
"[5080125.44708045]]), '10027': Matrix([\n",
"[3794736.96000806],\n",
"[546879.602518143],\n",
"[5080106.77720197]]), '10028': Matrix([\n",
"[3794854.42558972],\n",
"[546891.260466949],\n",
"[5079988.55485218]]), '10029': Matrix([\n",
"[3794813.64192358],\n",
"[546903.641106338],\n",
"[5080022.06775364]]), '10030': Matrix([\n",
"[3794814.74562118],\n",
"[546890.757518605],\n",
"[5080026.46489654]]), '10031': Matrix([\n",
"[3794794.79058969],\n",
"[ 546872.71612651],\n",
"[5080053.61063449]]), '10032': Matrix([\n",
"[3794781.55115635],\n",
"[546884.895506778],\n",
"[5080060.97408994]]), '10033': Matrix([\n",
"[3794775.28175346],\n",
"[546873.334968714],\n",
"[5080072.04785473]]), '10034': Matrix([\n",
"[3794847.88993759],\n",
"[546944.410223245],\n",
"[5079972.30963836]]), '10035': Matrix([\n",
"[3794811.83097489],\n",
"[546946.723835994],\n",
"[5080006.35848061]]), '10036': Matrix([\n",
"[3794783.39377131],\n",
"[546958.852789368],\n",
"[5080028.37568321]]), '10038': Matrix([\n",
"[3794777.81558632],\n",
"[546923.349922253],\n",
"[5080048.80883121]]), '10039': Matrix([\n",
"[3794776.73400961],\n",
"[546909.821579998],\n",
"[5080055.59246981]]), '10040': Matrix([\n",
"[3794753.10534012],\n",
"[546951.926584076],\n",
"[5080060.54410929]]), '10041': Matrix([\n",
"[3794752.59165627],\n",
"[546924.173873934],\n",
"[5080073.19205182]]), '10042': Matrix([\n",
"[ 3794734.5543882],\n",
"[546937.377006367],\n",
"[ 5080084.7094339]]), '10043': Matrix([\n",
"[3794725.01661161],\n",
"[546922.581244633],\n",
"[5080100.03703997]]), '10045': Matrix([\n",
"[3794840.94124498],\n",
"[546995.029310828],\n",
"[5079957.56668261]]), '10046': Matrix([\n",
"[3794809.35039725],\n",
"[546994.054056815],\n",
"[5079987.99204381]]), '10047': Matrix([\n",
"[ 3794795.4368399],\n",
"[547001.195960895],\n",
"[5079998.39175117]]), '10048': Matrix([\n",
"[3794775.20666754],\n",
"[ 547003.76019026],\n",
"[5080016.84921095]]), '10049': Matrix([\n",
"[ 3794755.2599089],\n",
"[547011.179377653],\n",
"[5080033.23331374]]), '10049a': Matrix([\n",
"[3794754.91370463],\n",
"[ 547010.69453884],\n",
"[5080033.75043702]]), '10050': Matrix([\n",
"[3794737.22036781],\n",
"[547005.884569236],\n",
"[ 5080052.9475627]]), '10051': Matrix([\n",
"[3794738.87891047],\n",
"[546983.860512271],\n",
"[5080060.85649738]]), '10052': Matrix([\n",
"[3794717.92069948],\n",
"[ 546983.44591806],\n",
"[5080081.08810058]]), '10053': Matrix([\n",
"[3794720.08539271],\n",
"[547013.409039769],\n",
"[ 5080066.3657566]]), '10054': Matrix([\n",
"[3794843.61283972],\n",
"[547056.002453676],\n",
"[5079929.24030295]]), '10055': Matrix([\n",
"[ 3794798.3440481],\n",
"[547058.886596772],\n",
"[5079971.04209003]]), '10056': Matrix([\n",
"[3794785.08794943],\n",
"[547072.889218702],\n",
"[5079977.73770134]]), '10057': Matrix([\n",
"[3794764.13960343],\n",
"[ 547061.72963122],\n",
"[5080002.94483388]]), '10058': Matrix([\n",
"[3794731.98341087],\n",
"[547079.121468109],\n",
"[5080026.61270465]]), '10059': Matrix([\n",
"[3794706.22500851],\n",
"[547072.229773112],\n",
"[5080054.43002136]])}\n"
]
}
],
"execution_count": 20
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-09T13:25:19.224013Z",
"start_time": "2025-12-09T13:25:19.204366Z"
}
},
"cell_type": "code",
"source": [
"importlib.reload(Datenbank)\n",
"db_zugriff = Datenbank.Datenbankzugriff(pfad_datenbank)\n",
"\n",
"db_zugriff.set_koordinaten(koordinaten_transformiert, \"naeherung_us\")"
],
"id": "f6993d81c8a145dd",
"outputs": [],
"execution_count": 24
}
],
"metadata": {

View File

@@ -51,3 +51,12 @@
10029;909,3343;1814,8767;99,5486;
10034;860,2357;1758,9282;99,7370;
10045;867,2324;1705,0630;99,7214;
10049a;985,2561;1715,2109;99,9965;
10048;957,3889;1716,2949;99,7212;
10047;929,5334;1712,6429;99,6076;
10046;910,6630;1716,0969;99,5459;
10057;969,6876;1655,5970;99,7039;
10055;922,4731;1647,7452;99,4658;
10054;860,4481;1636,6722;99,7093;
10058;1013,2592;1646,6356;99,8513;
10056;939,9763;1636,4179;99,4027;
1 10009 1000,0000 2000,0000 100,0000
51 10029 909,3343 1814,8767 99,5486
52 10034 860,2357 1758,9282 99,7370
53 10045 867,2324 1705,0630 99,7214
54 10049a 985,2561 1715,2109 99,9965
55 10048 957,3889 1716,2949 99,7212
56 10047 929,5334 1712,6429 99,6076
57 10046 910,6630 1716,0969 99,5459
58 10057 969,6876 1655,5970 99,7039
59 10055 922,4731 1647,7452 99,4658
60 10054 860,4481 1636,6722 99,7093
61 10058 1013,2592 1646,6356 99,8513
62 10056 939,9763 1636,4179 99,4027

View File

@@ -32,11 +32,13 @@ class Datenbankzugriff:
def __init__(self, pfad_datenbank):
self.pfad_datenbank = pfad_datenbank
def get_koordinaten(self, koordinatenart, ausgabeart = "Vektoren"):
def get_koordinaten(self, koordinatenart, ausgabeart = "Dict"):
con = sqlite3.connect(self.pfad_datenbank)
cursor = con.cursor()
if koordinatenart == "naeherung_lh":
values = "punktnummer, naeherungx_lh, naeherungy_lh, naeherungz_lh"
elif koordinatenart == "naeherung_us":
values = "punktnummer, naeherungx_us, naeherungy_us, naeherungz_us"
liste_koordinaten = cursor.execute(f"""
SELECT {values} FROM Netzpunkte;
@@ -44,9 +46,33 @@ class Datenbankzugriff:
cursor.close()
con.close()
if ausgabeart == "Vektoren":
liste_koordinaten_vektoren = []
for koordinate in liste_koordinaten:
liste_koordinaten_vektoren.append({koordinate[0]: sp.Matrix([float(koordinate[1]), float(koordinate[2]), float(koordinate[3])])})
liste_koordinaten = liste_koordinaten_vektoren
return liste_koordinaten
liste_koordinaten = [
koordinate for koordinate in liste_koordinaten
if koordinate[1] is not None and koordinate[2] is not None and koordinate[3] is not None
]
if ausgabeart == "Dict":
return {koordinate[0]: sp.Matrix([float(koordinate[1]), float(koordinate[2]), float(koordinate[3])]) for koordinate in liste_koordinaten}
def set_koordinaten(self, dict_koordinaten, koordinatenart):
con = sqlite3.connect(self.pfad_datenbank)
cursor = con.cursor()
daten = []
for punktnummer, wert in dict_koordinaten.items():
daten.append((
float(wert[0]),
float(wert[1]),
float(wert[2]),
str(punktnummer)
))
if koordinatenart == "naeherung_lh":
pass
elif koordinatenart == "naeherung_us":
cursor.executemany(f"""UPDATE Netzpunkte SET naeherungx_us = ?, naeherungy_us = ?, naeherungz_us = ? WHERE punktnummer = ? AND naeherungx_us IS NULL AND naeherungy_us IS NULL AND naeherungz_us IS NULL""", daten)
con.commit()
cursor.close()
con.close()

View File

@@ -0,0 +1,282 @@
import sympy as sp
from sympy.algebras.quaternion import Quaternion
import Datenbank
from itertools import combinations
class Transformationen:
def __init__(self, pfad_datenbank):
self.pfad_datenbank = pfad_datenbank
@staticmethod
def R_matrix_aus_euler(e1, e2, e3):
return sp.Matrix([
[
sp.cos(e2) * sp.cos(e3),
sp.cos(e1) * sp.sin(e3) + sp.sin(e1) * sp.sin(e2) * sp.cos(e3),
sp.sin(e1) * sp.sin(e3) - sp.cos(e1) * sp.sin(e2) * sp.cos(e3)
],
[
-sp.cos(e2) * sp.sin(e3),
sp.cos(e1) * sp.cos(e3) - sp.sin(e1) * sp.sin(e2) * sp.sin(e3),
sp.sin(e1) * sp.cos(e3) + sp.cos(e1) * sp.sin(e2) * sp.sin(e3)
],
[
sp.sin(e2),
-sp.sin(e1) * sp.cos(e2),
sp.cos(e1) * sp.cos(e2)
]
])
def Helmerttransformation_Euler_Transformationsparameter_berechne(self):
db = Datenbank.Datenbankzugriff(self.pfad_datenbank)
dict_ausgangssystem = db.get_koordinaten("naeherung_lh", "Dict")
dict_zielsystem = db.get_koordinaten("naeherung_us", "Dict")
gemeinsame_punktnummern = sorted(set(dict_ausgangssystem.keys()) & set(dict_zielsystem.keys()))
anzahl_gemeinsame_punkte = len(gemeinsame_punktnummern)
liste_punkte_ausgangssystem = [dict_ausgangssystem[i] for i in gemeinsame_punktnummern]
liste_punkte_zielsystem = [dict_zielsystem[i] for i in gemeinsame_punktnummern]
print("Anzahl gemeinsame Punkte:", anzahl_gemeinsame_punkte)
print("\nErste Zielpunkte:")
for pn, P in list(zip(gemeinsame_punktnummern, liste_punkte_zielsystem))[:5]:
print(pn, [float(P[0]), float(P[1]), float(P[2])])
print("\nErste Ausgangspunkte:")
for pn, p in list(zip(gemeinsame_punktnummern, liste_punkte_ausgangssystem))[:5]:
print(pn, [float(p[0]), float(p[1]), float(p[2])])
# --- Näherungswerte (minimal erweitert) ---
p1, p2, p3 = liste_punkte_ausgangssystem[0], liste_punkte_ausgangssystem[1], liste_punkte_ausgangssystem[2]
P1, P2, P3 = liste_punkte_zielsystem[0], liste_punkte_zielsystem[1], liste_punkte_zielsystem[2]
# 1) Näherungswert Maßstab: Mittelwert aus allen Punktpaaren
ratios = []
for i, j in combinations(range(anzahl_gemeinsame_punkte), 2):
dp = (liste_punkte_ausgangssystem[j] - liste_punkte_ausgangssystem[i]).norm()
dP = (liste_punkte_zielsystem[j] - liste_punkte_zielsystem[i]).norm()
dp_f = float(dp)
if dp_f > 0:
ratios.append(float(dP) / dp_f)
m0 = sum(ratios) / len(ratios)
if ratios:
print("min/mean/max:",
min(ratios),
sum(ratios) / len(ratios),
max(ratios))
U = (P2 - P1) / (P2 - P1).norm()
W = (U.cross(P3 - P1)) / (U.cross(P3 - P1)).norm()
V = W.cross(U)
u = (p2 - p1) / (p2 - p1).norm()
w = (u.cross(p3 - p1)) / (u.cross(p3 - p1)).norm()
v = w.cross(u)
R0 = sp.Matrix.hstack(U, V, W) * sp.Matrix.hstack(u, v, w).T
XS = sum(liste_punkte_zielsystem, sp.Matrix([0, 0, 0])) / anzahl_gemeinsame_punkte
xS = sum(liste_punkte_ausgangssystem, sp.Matrix([0, 0, 0])) / anzahl_gemeinsame_punkte
Translation0 = XS - m0 * R0 * xS
# 2) Test auf orthonormale Drehmatrix bei 3 Nachkommastellen!
if R0.T.applyfunc(lambda x: round(float(x), 3)) == R0.inv().applyfunc(lambda x: round(float(x), 3)) \
and (R0.T * R0).applyfunc(lambda x: round(float(x), 3)) == sp.eye(3).applyfunc(
lambda x: round(float(x), 3)) \
and ((round(R0.det(), 3) == 1.000 or round(R0.det(), 3) == -1.000)):
print("R ist Orthonormal!")
else:
print("R ist nicht Orthonormal!")
# 3) Euler-Näherungswerte aus R0
e2_0 = sp.asin(R0[2, 0])
# Schutz gegen Division durch 0 wenn cos(e2) ~ 0:
cos_e2_0 = sp.cos(e2_0)
e1_0 = sp.acos(R0[2, 2] / cos_e2_0)
e3_0 = sp.acos(R0[0, 0] / cos_e2_0)
# --- Symbolische Unbekannte (klassische 7 Parameter) ---
dX, dY, dZ, m, e1, e2, e3 = sp.symbols('dX dY dZ m e1 e2 e3')
R_symbolisch = self.R_matrix_aus_euler(e1, e2, e3)
# 4) Funktionales Modell
f_zeilen = []
for punkt in liste_punkte_ausgangssystem:
punkt_vektor = sp.Matrix([punkt[0], punkt[1], punkt[2]])
f_zeile_i = sp.Matrix([dX, dY, dZ]) + m * R_symbolisch * punkt_vektor
f_zeilen.extend(list(f_zeile_i))
f_matrix = sp.Matrix(f_zeilen)
f = f_matrix
A_ohne_zahlen = f_matrix.jacobian([dX, dY, dZ, m, e1, e2, e3])
# Parameterschätzung
schwellenwert = 1e-4
anzahl_iterationen = 0
alle_kleiner_vorherige_iteration = False
l_vektor = sp.Matrix([koord for P in liste_punkte_zielsystem for koord in P])
l = l_vektor
P_mat = sp.eye(3 * anzahl_gemeinsame_punkte)
l_berechnet_0 = None
while True:
if anzahl_iterationen == 0:
zahlen_0 = {
dX: float(Translation0[0]),
dY: float(Translation0[1]),
dZ: float(Translation0[2]),
m: float(m0),
e1: float(e1_0),
e2: float(e2_0),
e3: float(e3_0)
}
x0 = sp.Matrix([zahlen_0[dX], zahlen_0[dY], zahlen_0[dZ],
zahlen_0[m], zahlen_0[e1], zahlen_0[e2], zahlen_0[e3]])
l_berechnet_0 = f.subs(zahlen_0).evalf(n=30)
dl_0 = l_vektor - l_berechnet_0
A_0 = A_ohne_zahlen.subs(zahlen_0).evalf(n=30)
N = A_0.T * P_mat * A_0
n_0 = A_0.T * P_mat * dl_0
Qxx_0 = N.inv()
dx = Qxx_0 * n_0
x = x0 + dx
x = sp.N(x, 30)
anzahl_iterationen += 1
print(f"Iteration Nr.{anzahl_iterationen} abgeschlossen")
print(dx.evalf(n=3))
else:
zahlen_i = {
dX: float(x[0]),
dY: float(x[1]),
dZ: float(x[2]),
m: float(x[3]),
e1: float(x[4]),
e2: float(x[5]),
e3: float(x[6])
}
l_berechnet_i = f.subs(zahlen_i).evalf(n=30)
dl_i = l_vektor - l_berechnet_i
A_i = A_ohne_zahlen.subs(zahlen_i).evalf(n=30)
N_i = A_i.T * P_mat * A_i
Qxx_i = N_i.inv()
n_i = A_i.T * P_mat * dl_i
dx = Qxx_i * n_i
x = sp.Matrix(x + dx)
anzahl_iterationen += 1
print(f"Iteration Nr.{anzahl_iterationen} abgeschlossen")
print(dx.evalf(n=3))
alle_kleiner = True
for i in range(dx.rows):
wert = float(dx[i])
if abs(wert) > schwellenwert:
alle_kleiner = False
if (alle_kleiner and alle_kleiner_vorherige_iteration) or anzahl_iterationen == 100:
break
alle_kleiner_vorherige_iteration = alle_kleiner
print(l.evalf(n=3))
print(l_berechnet_0.evalf(n=3))
print(f"x = {x.evalf(n=3)}")
# --- Neuberechnung Zielsystem ---
zahlen_final = {
dX: float(x[0]),
dY: float(x[1]),
dZ: float(x[2]),
m: float(x[3]),
e1: float(x[4]),
e2: float(x[5]),
e3: float(x[6])
}
l_berechnet_final = f.subs(zahlen_final).evalf(n=30)
liste_l_berechnet_final = []
for i in range(anzahl_gemeinsame_punkte):
Xi = l_berechnet_final[3 * i + 0]
Yi = l_berechnet_final[3 * i + 1]
Zi = l_berechnet_final[3 * i + 2]
liste_l_berechnet_final.append(sp.Matrix([Xi, Yi, Zi]))
print("")
print("l_berechnet_final:")
for punktnummer, l_fin in zip(gemeinsame_punktnummern, liste_l_berechnet_final):
print(f"{punktnummer}: {float(l_fin[0]):.3f}, {float(l_fin[1]):.3f}, {float(l_fin[2]):.3f}")
print("Streckendifferenzen:")
streckendifferenzen = [
(punkt_zielsys - l_final).norm()
for punkt_zielsys, l_final in zip(liste_punkte_zielsystem, liste_l_berechnet_final)
]
print([round(float(s), 6) for s in streckendifferenzen])
Schwerpunkt_Zielsystem = sum(liste_punkte_zielsystem, sp.Matrix([0, 0, 0])) / anzahl_gemeinsame_punkte
Schwerpunkt_berechnet = sum(liste_l_berechnet_final, sp.Matrix([0, 0, 0])) / anzahl_gemeinsame_punkte
Schwerpunktsdifferenz = Schwerpunkt_Zielsystem - Schwerpunkt_berechnet
print("\nDifferenz Schwerpunkt (Vektor):")
print(Schwerpunktsdifferenz.evalf(3))
print("Betrag der Schwerpunkt-Differenz:")
print(f"{float(Schwerpunktsdifferenz.norm()):.3f}m")
return zahlen_final
def Helmerttransformation(self, transformationsparameter):
db = Datenbank.Datenbankzugriff(self.pfad_datenbank)
dict_ausgangssystem = db.get_koordinaten("naeherung_lh", "Dict")
dict_zielsystem = db.get_koordinaten("naeherung_us", "Dict")
dX, dY, dZ, m, e1, e2, e3 = sp.symbols('dX dY dZ m e1 e2 e3')
unterschiedliche_punktnummern = sorted(set(dict_ausgangssystem.keys()) ^ set(dict_zielsystem.keys()))
punktnummern_transformieren = [
punktnummer for punktnummer in unterschiedliche_punktnummern if punktnummer in dict_ausgangssystem
]
liste_punkte_ausgangssystem = [dict_ausgangssystem[punktnummer] for punktnummer in punktnummern_transformieren]
R = self.R_matrix_aus_euler(transformationsparameter[e1], transformationsparameter[e2], transformationsparameter[e3])
f_zeilen = []
for punkt in liste_punkte_ausgangssystem:
punkt_vektor = sp.Matrix([punkt[0], punkt[1], punkt[2]])
f_zeile_i = sp.Matrix([transformationsparameter[dX], transformationsparameter[dY], transformationsparameter[dZ]]) + transformationsparameter[m] * R * punkt_vektor
f_zeilen.extend(list(f_zeile_i))
f_matrix = sp.Matrix(f_zeilen)
dict_transformiert = {}
for i, pn in enumerate(punktnummern_transformieren):
Xi = f_matrix[3 * i + 0]
Yi = f_matrix[3 * i + 1]
Zi = f_matrix[3 * i + 2]
dict_transformiert[str(pn)] = sp.Matrix([
[float(Xi)],
[float(Yi)],
[float(Zi)]
])
return dict_transformiert

View File

@@ -0,0 +1,208 @@
@staticmethod
def R_matrix_aus_quaternion(q0, q1, q2, q3):
return sp.Matrix([
[1 - 2 * (q2 ** 2 + q3 ** 2), 2 * (q1 * q2 - q0 * q3), 2 * (q0 * q2 + q1 * q3)],
[2 * (q1 * q2 + q0 * q3), 1 - 2 * (q1 ** 2 + q3 ** 2), 2 * (q2 * q3 - q0 * q1)],
[2 * (q1 * q3 - q0 * q2), 2 * (q0 * q1 + q2 * q3), 1 - 2 * (q1 ** 2 + q2 ** 2)]
])
def Helmerttransformation_Quaternionen(self):
db = Datenbank.Datenbankzugriff(self.pfad_datenbank)
dict_ausgangssystem = db.get_koordinaten("naeherung_lh", "Dict")
dict_zielsystem = db.get_koordinaten("naeherung_us", "Dict")
gemeinsame_punktnummern = sorted(set(dict_ausgangssystem.keys()) & set(dict_zielsystem.keys()))
anzahl_gemeinsame_punkte = len(gemeinsame_punktnummern)
liste_punkte_ausgangssystem = [dict_ausgangssystem[i] for i in gemeinsame_punktnummern]
liste_punkte_zielsystem = [dict_zielsystem[i] for i in gemeinsame_punktnummern]
print("Anzahl gemeinsame Punkte:", anzahl_gemeinsame_punkte)
print("\nErste Zielpunkte:")
for pn, P in list(zip(gemeinsame_punktnummern, liste_punkte_zielsystem))[:5]:
print(pn, [float(P[0]), float(P[1]), float(P[2])])
print("\nErste Ausgangspunkte:")
for pn, p in list(zip(gemeinsame_punktnummern, liste_punkte_ausgangssystem))[:5]:
print(pn, [float(p[0]), float(p[1]), float(p[2])])
# ToDo: Achtung: Die Ergebnisse sind leicht anders, als in den Beispielrechnung von Luhmann (Rundungsfehler bei Luhmann?)
# ToDo: Automatische Ermittlung der Anzahl Nachkommastellen für Test auf Orthonormalität integrieren!
p1, p2, p3 = liste_punkte_ausgangssystem[0], liste_punkte_ausgangssystem[1], liste_punkte_ausgangssystem[2]
P1, P2, P3 = liste_punkte_zielsystem[0], liste_punkte_zielsystem[1], liste_punkte_zielsystem[2]
# 1) Näherungswertberechnung
m0 = (P2 - P1).norm() / (p2 - p1).norm()
U = (P2 - P1) / (P2 - P1).norm()
W = (U.cross(P3 - P1)) / (U.cross(P3 - P1)).norm()
V = W.cross(U)
u = (p2 - p1) / (p2 - p1).norm()
w = (u.cross(p3 - p1)) / (u.cross(p3 - p1)).norm()
v = w.cross(u)
R = sp.Matrix.hstack(U, V, W) * sp.Matrix.hstack(u, v, w).T
XS = (P1 + P2 + P3) / 3
xS = (p1 + p2 + p3) / 3
Translation = XS - m0 * R * xS
# 2) Test auf orthonormale Drehmatrix bei 3 Nachkommastellen!
if R.T.applyfunc(lambda x: round(float(x), 3)) == R.inv().applyfunc(lambda x: round(float(x), 3)) and (
R.T * R).applyfunc(lambda x: round(float(x), 3)) == sp.eye(3).applyfunc(lambda x: round(float(x), 3)) and (
(round(R.det(), 3) == 1.000 or round(R.det(), 3) == -1.000)):
print("R ist Orthonormal!")
else:
print("R ist nicht Orthonormal!")
# 3) Quaternionen berechnen
# ToDo: Prüfen, ob Vorzeichen bei q0 richtig ist!
# ToDo: q0 stimmt nicht mit Luhmann überein!
q = Quaternion.from_rotation_matrix(R)
q0_wert = q.a
q1_wert = q.b
q2_wert = q.c
q3_wert = q.d
dX, dY, dZ, m, q0, q1, q2, q3 = sp.symbols('dX dY dZ m q0 q1 q2 q3')
R_symbolisch = self.R_matrix_aus_quaternion(q0, q1, q2, q3)
# 4) Funktionales Modell
f_zeilen = []
for punkt in liste_punkte_ausgangssystem:
punkt_vektor = sp.Matrix([punkt[0], punkt[1], punkt[2]])
f_zeile_i = sp.Matrix([dX, dY, dZ]) + m * R_symbolisch * punkt_vektor
f_zeilen.extend(list(f_zeile_i))
f_matrix = sp.Matrix(f_zeilen)
f = f_matrix
A_ohne_zahlen = f_matrix.jacobian([dX, dY, dZ, m, q0, q1, q2, q3])
# Parameterschätzung
schwellenwert = 1e-4
anzahl_iterationen = 0
alle_kleiner_vorherige_iteration = False
l_vektor = sp.Matrix([koord for P in liste_punkte_zielsystem for koord in P])
l = l_vektor
P = sp.eye(3 * anzahl_gemeinsame_punkte)
l_berechnet_0 = None
while True:
if anzahl_iterationen == 0:
zahlen_0 = {dX: float(Translation[0]), dY: float(Translation[1]), dZ: float(Translation[2]), m: float(m0),
q0: float(q0_wert), q1: float(q1_wert),
q2: float(q2_wert),
q3: float(q3_wert)}
x0 = sp.Matrix(
[zahlen_0[dX], zahlen_0[dY], zahlen_0[dZ], zahlen_0[m], zahlen_0[q0], zahlen_0[q1], zahlen_0[q2],
zahlen_0[q3]])
l_berechnet_0 = f.subs(zahlen_0).evalf(n=30)
dl_0 = l_vektor - l_berechnet_0
A_0 = A_ohne_zahlen.subs(zahlen_0).evalf(n=30)
N = A_0.T * P * A_0
n_0 = A_0.T * P * dl_0
Qxx_0 = N.inv()
dx = Qxx_0 * n_0
x = x0 + dx
x = sp.N(x, 30) # 30 Nachkommastellen
q_norm = sp.sqrt(x[4] ** 2 + x[5] ** 2 + x[6] ** 2 + x[7] ** 2)
x = sp.Matrix(x)
x[4] /= q_norm
x[5] /= q_norm
x[6] /= q_norm
x[7] /= q_norm
anzahl_iterationen += 1
print(f"Iteration Nr.{anzahl_iterationen} abgeschlossen")
print(dx.evalf(n=3))
else:
zahlen_i = {dX: float(x[0]), dY: float(x[1]), dZ: float(x[2]), m: float(x[3]), q0: float(x[4]),
q1: float(x[5]),
q2: float(x[6]),
q3: float(x[7])}
l_berechnet_i = f.subs(zahlen_i).evalf(n=30)
dl_i = l_vektor - l_berechnet_i
A_i = A_ohne_zahlen.subs(zahlen_i).evalf(n=30)
N_i = A_i.T * P * A_i
Qxx_i = N_i.inv()
n_i = A_i.T * P * dl_i
dx = Qxx_i * n_i
x = sp.Matrix(x + dx)
q_norm = sp.sqrt(x[4] ** 2 + x[5] ** 2 + x[6] ** 2 + x[7] ** 2)
x[4] /= q_norm
x[5] /= q_norm
x[6] /= q_norm
x[7] /= q_norm
anzahl_iterationen += 1
print(f"Iteration Nr.{anzahl_iterationen} abgeschlossen")
print(dx.evalf(n=3))
alle_kleiner = True
for i in range(dx.rows):
wert = float(dx[i])
if abs(wert) > schwellenwert:
alle_kleiner = False
if alle_kleiner and alle_kleiner_vorherige_iteration or anzahl_iterationen == 100:
break
alle_kleiner_vorherige_iteration = alle_kleiner
print(l.evalf(n=3))
print(l_berechnet_0.evalf(n=3))
print(f"x = {x.evalf(n=3)}")
# Neuberechnung Zielsystem
zahlen_final = {
dX: float(x[0]),
dY: float(x[1]),
dZ: float(x[2]),
m: float(x[3]),
q0: float(x[4]),
q1: float(x[5]),
q2: float(x[6]),
q3: float(x[7])
}
l_berechnet_final = f.subs(zahlen_final).evalf(n=30)
liste_l_berechnet_final = []
for i in range(anzahl_gemeinsame_punkte):
Xi = l_berechnet_final[3 * i + 0]
Yi = l_berechnet_final[3 * i + 1]
Zi = l_berechnet_final[3 * i + 2]
liste_l_berechnet_final.append(sp.Matrix([Xi, Yi, Zi]))
print("")
print("l_berechnet_final:")
for punktnummer, l_fin in zip(gemeinsame_punktnummern, liste_l_berechnet_final):
print(f"{punktnummer}: {float(l_fin[0]):.3f}, {float(l_fin[1]):.3f}, {float(l_fin[2]):.3f}")
print("Streckendifferenzen:")
streckendifferenzen = [
(punkt_zielsys - l_final).norm()
for punkt_zielsys, l_final in zip(liste_punkte_zielsystem, liste_l_berechnet_final)
]
print([round(float(s), 6) for s in streckendifferenzen])
Schwerpunkt_Zielsystem = sum(liste_punkte_zielsystem, sp.Matrix([0, 0, 0])) / anzahl_gemeinsame_punkte
Schwerpunkt_berechnet = sum(liste_l_berechnet_final, sp.Matrix([0, 0, 0])) / anzahl_gemeinsame_punkte
Schwerpunktsdifferenz = Schwerpunkt_Zielsystem - Schwerpunkt_berechnet
print("\nDifferenz Schwerpunkt (Vektor):")
print(Schwerpunktsdifferenz.evalf(3))
print("Betrag der Schwerpunkt-Differenz:")
print(f"{float(Schwerpunktsdifferenz.norm()):.3f}m")
# ToDo: Abweichungen in Printausgabe ausgeben!

View File

@@ -266,3 +266,217 @@ print("Betrag der Schwerpunkt-Differenz:")
print(f"{float(Schwerpunktsdifferenz.norm()):.3f}m")
#ToDo: Abweichungen in Printausgabe ausgeben!
def Helmerttransformation_Euler(self):
db = Datenbank.Datenbankzugriff(self.pfad_datenbank)
dict_ausgangssystem = db.get_koordinaten("naeherung_lh", "Dict")
dict_zielsystem = db.get_koordinaten("naeherung_us", "Dict")
gemeinsame_punktnummern = sorted(set(dict_ausgangssystem.keys()) & set(dict_zielsystem.keys()))
anzahl_gemeinsame_punkte = len(gemeinsame_punktnummern)
liste_punkte_ausgangssystem = [dict_ausgangssystem[i] for i in gemeinsame_punktnummern]
liste_punkte_zielsystem = [dict_zielsystem[i] for i in gemeinsame_punktnummern]
print("Anzahl gemeinsame Punkte:", anzahl_gemeinsame_punkte)
print("\nErste Zielpunkte:")
for pn, P in list(zip(gemeinsame_punktnummern, liste_punkte_zielsystem))[:5]:
print(pn, [float(P[0]), float(P[1]), float(P[2])])
print("\nErste Ausgangspunkte:")
for pn, p in list(zip(gemeinsame_punktnummern, liste_punkte_ausgangssystem))[:5]:
print(pn, [float(p[0]), float(p[1]), float(p[2])])
# --- Näherungswerte (minimal erweitert) ---
p1, p2, p3 = liste_punkte_ausgangssystem[0], liste_punkte_ausgangssystem[1], liste_punkte_ausgangssystem[2]
P1, P2, P3 = liste_punkte_zielsystem[0], liste_punkte_zielsystem[1], liste_punkte_zielsystem[2]
# 1) Näherungswert Maßstab: Mittelwert aus allen Punktpaaren
ratios = []
for i, j in combinations(range(anzahl_gemeinsame_punkte), 2):
dp = (liste_punkte_ausgangssystem[j] - liste_punkte_ausgangssystem[i]).norm()
dP = (liste_punkte_zielsystem[j] - liste_punkte_zielsystem[i]).norm()
dp_f = float(dp)
if dp_f > 0:
ratios.append(float(dP) / dp_f)
m0 = sum(ratios) / len(ratios)
if ratios:
print("min/mean/max:",
min(ratios),
sum(ratios) / len(ratios),
max(ratios))
U = (P2 - P1) / (P2 - P1).norm()
W = (U.cross(P3 - P1)) / (U.cross(P3 - P1)).norm()
V = W.cross(U)
u = (p2 - p1) / (p2 - p1).norm()
w = (u.cross(p3 - p1)) / (u.cross(p3 - p1)).norm()
v = w.cross(u)
R0 = sp.Matrix.hstack(U, V, W) * sp.Matrix.hstack(u, v, w).T
XS = sum(liste_punkte_zielsystem, sp.Matrix([0, 0, 0])) / anzahl_gemeinsame_punkte
xS = sum(liste_punkte_ausgangssystem, sp.Matrix([0, 0, 0])) / anzahl_gemeinsame_punkte
Translation0 = XS - m0 * R0 * xS
# 2) Test auf orthonormale Drehmatrix bei 3 Nachkommastellen!
if R0.T.applyfunc(lambda x: round(float(x), 3)) == R0.inv().applyfunc(lambda x: round(float(x), 3)) \
and (R0.T * R0).applyfunc(lambda x: round(float(x), 3)) == sp.eye(3).applyfunc(lambda x: round(float(x), 3)) \
and ((round(R0.det(), 3) == 1.000 or round(R0.det(), 3) == -1.000)):
print("R ist Orthonormal!")
else:
print("R ist nicht Orthonormal!")
# 3) Euler-Näherungswerte aus R0
e2_0 = sp.asin(R0[2, 0])
# Schutz gegen Division durch 0 wenn cos(e2) ~ 0:
cos_e2_0 = sp.cos(e2_0)
e1_0 = sp.acos(R0[2, 2] / cos_e2_0)
e3_0 = sp.acos(R0[0, 0] / cos_e2_0)
# --- Symbolische Unbekannte (klassische 7 Parameter) ---
dX, dY, dZ, m, e1, e2, e3 = sp.symbols('dX dY dZ m e1 e2 e3')
R_symbolisch = self.R_matrix_aus_euler(e1, e2, e3)
# 4) Funktionales Modell
f_zeilen = []
for punkt in liste_punkte_ausgangssystem:
punkt_vektor = sp.Matrix([punkt[0], punkt[1], punkt[2]])
f_zeile_i = sp.Matrix([dX, dY, dZ]) + m * R_symbolisch * punkt_vektor
f_zeilen.extend(list(f_zeile_i))
f_matrix = sp.Matrix(f_zeilen)
f = f_matrix
A_ohne_zahlen = f_matrix.jacobian([dX, dY, dZ, m, e1, e2, e3])
# Parameterschätzung
schwellenwert = 1e-4
anzahl_iterationen = 0
alle_kleiner_vorherige_iteration = False
l_vektor = sp.Matrix([koord for P in liste_punkte_zielsystem for koord in P])
l = l_vektor
P_mat = sp.eye(3 * anzahl_gemeinsame_punkte)
l_berechnet_0 = None
while True:
if anzahl_iterationen == 0:
zahlen_0 = {
dX: float(Translation0[0]),
dY: float(Translation0[1]),
dZ: float(Translation0[2]),
m: float(m0),
e1: float(e1_0),
e2: float(e2_0),
e3: float(e3_0)
}
x0 = sp.Matrix([zahlen_0[dX], zahlen_0[dY], zahlen_0[dZ],
zahlen_0[m], zahlen_0[e1], zahlen_0[e2], zahlen_0[e3]])
l_berechnet_0 = f.subs(zahlen_0).evalf(n=30)
dl_0 = l_vektor - l_berechnet_0
A_0 = A_ohne_zahlen.subs(zahlen_0).evalf(n=30)
N = A_0.T * P_mat * A_0
n_0 = A_0.T * P_mat * dl_0
Qxx_0 = N.inv()
dx = Qxx_0 * n_0
x = x0 + dx
x = sp.N(x, 30)
anzahl_iterationen += 1
print(f"Iteration Nr.{anzahl_iterationen} abgeschlossen")
print(dx.evalf(n=3))
else:
zahlen_i = {
dX: float(x[0]),
dY: float(x[1]),
dZ: float(x[2]),
m: float(x[3]),
e1: float(x[4]),
e2: float(x[5]),
e3: float(x[6])
}
l_berechnet_i = f.subs(zahlen_i).evalf(n=30)
dl_i = l_vektor - l_berechnet_i
A_i = A_ohne_zahlen.subs(zahlen_i).evalf(n=30)
N_i = A_i.T * P_mat * A_i
Qxx_i = N_i.inv()
n_i = A_i.T * P_mat * dl_i
dx = Qxx_i * n_i
x = sp.Matrix(x + dx)
anzahl_iterationen += 1
print(f"Iteration Nr.{anzahl_iterationen} abgeschlossen")
print(dx.evalf(n=3))
alle_kleiner = True
for i in range(dx.rows):
wert = float(dx[i])
if abs(wert) > schwellenwert:
alle_kleiner = False
if (alle_kleiner and alle_kleiner_vorherige_iteration) or anzahl_iterationen == 100:
break
alle_kleiner_vorherige_iteration = alle_kleiner
print(l.evalf(n=3))
print(l_berechnet_0.evalf(n=3))
print(f"x = {x.evalf(n=3)}")
# --- Neuberechnung Zielsystem ---
zahlen_final = {
dX: float(x[0]),
dY: float(x[1]),
dZ: float(x[2]),
m: float(x[3]),
e1: float(x[4]),
e2: float(x[5]),
e3: float(x[6])
}
l_berechnet_final = f.subs(zahlen_final).evalf(n=30)
liste_l_berechnet_final = []
for i in range(anzahl_gemeinsame_punkte):
Xi = l_berechnet_final[3 * i + 0]
Yi = l_berechnet_final[3 * i + 1]
Zi = l_berechnet_final[3 * i + 2]
liste_l_berechnet_final.append(sp.Matrix([Xi, Yi, Zi]))
print("")
print("l_berechnet_final:")
for punktnummer, l_fin in zip(gemeinsame_punktnummern, liste_l_berechnet_final):
print(f"{punktnummer}: {float(l_fin[0]):.3f}, {float(l_fin[1]):.3f}, {float(l_fin[2]):.3f}")
print("Streckendifferenzen:")
streckendifferenzen = [
(punkt_zielsys - l_final).norm()
for punkt_zielsys, l_final in zip(liste_punkte_zielsystem, liste_l_berechnet_final)
]
print([round(float(s), 6) for s in streckendifferenzen])
Schwerpunkt_Zielsystem = sum(liste_punkte_zielsystem, sp.Matrix([0, 0, 0])) / anzahl_gemeinsame_punkte
Schwerpunkt_berechnet = sum(liste_l_berechnet_final, sp.Matrix([0, 0, 0])) / anzahl_gemeinsame_punkte
Schwerpunktsdifferenz = Schwerpunkt_Zielsystem - Schwerpunkt_berechnet
print("\nDifferenz Schwerpunkt (Vektor):")
print(Schwerpunktsdifferenz.evalf(3))
print("Betrag der Schwerpunkt-Differenz:")
print(f"{float(Schwerpunktsdifferenz.norm()):.3f}m")