From 270ea2b771b3cfc2dc1a97ad3368db873ccd0456 Mon Sep 17 00:00:00 2001 From: Arne Zitting Date: Mon, 11 May 2026 23:43:22 +0200 Subject: [PATCH] edited --- main.js | 134 +++++++++++++++++++++++++++++++--------------- package-lock.json | 66 ++++++++++++----------- package.json | 2 + 3 files changed, 129 insertions(+), 73 deletions(-) diff --git a/main.js b/main.js index 5c30c3b..3416775 100644 --- a/main.js +++ b/main.js @@ -1,4 +1,11 @@ import maplibregl from "maplibre-gl"; +import proj4 from "proj4"; +import * as THREE from "three"; +console.log(THREE); +proj4.defs( + "EPSG:25832", + "+proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs" +); const center = [9.209116842757239, 52.26520546238239] @@ -28,7 +35,6 @@ viewer.setPointBudget(3*1000*1000); viewer.setMinNodeSize(0); viewer.setBackground("none"); -//viewer.setControls(null); //Dateipfade der Punktwolken const pointCloudFiles={ @@ -37,6 +43,8 @@ const pointCloudFiles={ second: 'standpunkt2/metadata.json', third: 'punktwolke_3_converted/metadata.json', } + + //Aktuelle Datei und Sichtbarkeit let currentPointCloud=null; let isVisible=true; @@ -70,59 +78,99 @@ function loadPointCloud(path){ }); } -// Geo-Koordinaten der Punktwolke (müssen zu euren Daten passen!) -// Das ist der Georeferenzpunkt – idealerweise aus den Metadaten der Punktwolke -const CLOUD_GEO_ORIGIN = { - lng: 9.209116842757239, - lat: 52.26520546238239 -}; - -// Hilfsfunktion: MapLibre Mercator → Meter-Offset relativ zum Ursprung -function lngLatToMeters(lng, lat, originLng, originLat) { - const R = 6378137; // Erdradius in Metern (WGS84) - const dLng = (lng - originLng) * Math.PI / 180; - const dLat = (lat - originLat) * Math.PI / 180; - const dx = R * dLng * Math.cos(originLat * Math.PI / 180); - const dy = R * dLat; - return { x: dx, y: dy }; -} function syncCamera() { + if (!currentPointCloud) return; - const mapCenter = map.getCenter(); - const zoom = map.getZoom(); - const pitch = map.getPitch(); // Grad, 0 = top-down - const bearing = map.getBearing(); // Grad + const center = map.getCenter(); - const box = currentPointCloud.boundingBox; - const cx = (box.min.x + box.max.x) / 2; - const cy = (box.min.y + box.max.y) / 2; - const cz = (box.min.z + box.max.z) / 2; + // ----------------------------------------- + // WGS84 -> ETRS89 / UTM32 + // ----------------------------------------- - // Radius aus Zoom ableiten (Abstand Kamera → Target) - const earthCircumference = 2 * Math.PI * 6378137; - const canvas = map.getCanvas(); - const metersPerPixel = (earthCircumference * Math.cos(mapCenter.lat * Math.PI / 180)) - / (Math.pow(2, zoom) * 512); - const radius = Math.pow(2,20 -zoom)*2; + const [x, y] = proj4( + "EPSG:4326", + "EPSG:25832", + [center.lng, center.lat] + ); - // Potree View direkt setzen - const view = viewer.scene.view; + // ----------------------------------------- + // Map Parameter + // ----------------------------------------- - // Target = Wolken-Zentrum (lookAt mit 3 Argumenten nutzt new Vector3(...arguments)) - view.lookAt(cx, cy, cz); + const pitch = map.getPitch() * Math.PI / 180; + const bearing = map.getBearing() * Math.PI / 180; + const zoom = map.getZoom(); - // yaw = Himmelsrichtung: MapLibre bearing 0° = Nord, Potree yaw 0° = ?? - // bearing in Potree-yaw umrechnen (ggf. Vorzeichen anpassen) - view.yaw = -bearing * Math.PI / 180; + // ----------------------------------------- + // Abstand abhängig vom Zoom + // ----------------------------------------- - // pitch: MapLibre 0° = top-down, 60° = schräg - // Potree pitch: 0 = horizontal, -PI/2 = top-down → invertieren - view.pitch = -(90 - pitch) * Math.PI / 180; + const earthCircumference = 40075016.686; - // Radius = Zoom-abhängiger Abstand - view.radius = radius; + const metersPerPixel = + earthCircumference * + Math.cos(center.lat * Math.PI / 180) / + Math.pow(2, zoom + 8); + + const distance = + metersPerPixel * map.getCanvas().height; + + // ----------------------------------------- + // Zielpunkt = Kartenzentrum + // ----------------------------------------- + + const target = new THREE.Vector3( + x, + y, + 0 + ); + + // ----------------------------------------- + // Kameraoffset + // ----------------------------------------- + + const offset = new THREE.Vector3( + 0, + -distance * Math.cos(pitch), + distance * Math.sin(pitch) + ); + + // Bearing rotieren + offset.applyAxisAngle( + new THREE.Vector3(0, 0, 1), + -bearing + ); + + // ----------------------------------------- + // Kameraposition + // ----------------------------------------- + + const cameraPosition = + target.clone().add(offset); + + // ----------------------------------------- + // Potree Kamera setzen + // ----------------------------------------- + + const camera = + viewer.scene.getActiveCamera(); + + camera.position.copy(cameraPosition); + + camera.lookAt(target); + + viewer.scene.view.position.copy(cameraPosition); + + viewer.scene.view.lookAt(target); + + camera.updateMatrixWorld(); + + viewer.renderer.render( + viewer.scene.scene, + camera + ); } map.on('move', ()=>{ diff --git a/package-lock.json b/package-lock.json index 1a335b0..a0d8f89 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,8 @@ "@loaders.gl/las": "^4.4.1", "deck.gl": "^9.3.1", "maplibre-gl": "^5.22.0", + "proj4": "^2.20.8", + "three": "^0.184.0", "vite": "^8.0.7" } }, @@ -1380,9 +1382,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1399,9 +1398,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1418,9 +1414,6 @@ "cpu": [ "ppc64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1437,9 +1430,6 @@ "cpu": [ "s390x" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1456,9 +1446,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1475,9 +1462,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -4069,9 +4053,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -4092,9 +4073,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -4115,9 +4093,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -4138,9 +4113,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -4335,6 +4307,12 @@ "is-buffer": "~1.1.6" } }, + "node_modules/mgrs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mgrs/-/mgrs-1.0.0.tgz", + "integrity": "sha512-awNbTOqCxK1DBGjalK3xqWIstBZgN6fxsMSiXLs9/spqWkF2pAhb2rrYCFSsr1/tT7PhcDGjZndG8SWYn0byYA==", + "license": "MIT" + }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", @@ -4582,6 +4560,19 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, + "node_modules/proj4": { + "version": "2.20.8", + "resolved": "https://registry.npmjs.org/proj4/-/proj4-2.20.8.tgz", + "integrity": "sha512-1C8sfT4xY4PAPwk0MroFBTGF4R4bzDXdmPQTGYVLsoNssrZ9odzObxS2dTeGBty8jW8KO7h16C1Hs2JP+ctfFw==", + "license": "MIT", + "dependencies": { + "mgrs": "1.0.0", + "wkt-parser": "^1.5.5" + }, + "funding": { + "url": "https://github.com/sponsors/ahocevar" + } + }, "node_modules/protocol-buffers-schema": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.1.tgz", @@ -4924,6 +4915,12 @@ "texture-compressor": "bin/texture-compressor.js" } }, + "node_modules/three": { + "version": "0.184.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.184.0.tgz", + "integrity": "sha512-wtTRjG92pM5eUg/KuUnHsqSAlPM296brTOcLgMRqEeylYTh/CdtvKUvCyyCQTzFuStieWxvZb8mVTMvdPyUpxg==", + "license": "MIT" + }, "node_modules/timezone-groups": { "version": "0.10.4", "resolved": "https://registry.npmjs.org/timezone-groups/-/timezone-groups-0.10.4.tgz", @@ -5110,6 +5107,15 @@ } } }, + "node_modules/wkt-parser": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/wkt-parser/-/wkt-parser-1.5.5.tgz", + "integrity": "sha512-/zMYi94/7D7fxcOSlVmWn6vnOMj3Gq5d1xvVjaYOS9n6h0qOJ4I7YYVxBWYcH1vq9+suhqzXkn05Yx47zQNUIA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ahocevar" + } + }, "node_modules/wordwrapjs": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.1.tgz", diff --git a/package.json b/package.json index 910d0ad..aa4f7e5 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,8 @@ "@loaders.gl/las": "^4.4.1", "deck.gl": "^9.3.1", "maplibre-gl": "^5.22.0", + "proj4": "^2.20.8", + "three": "^0.184.0", "vite": "^8.0.7" } }