bugs gefixt

This commit is contained in:
2026-06-16 17:27:50 +02:00
parent 2951e18d3f
commit 792d515b2d
3 changed files with 36 additions and 57 deletions
+2 -7
View File
@@ -26,8 +26,7 @@
</header> </header>
<h1 id="title">- Obernkirchener Sandstein -</h1> <h1 id="title">- Obernkirchener Sandstein -</h1>
<div id="coordinates" title="Koordinaten an Mausposition"></div> <div id="coordinates" title="Koordinaten an Mausposition"></div>
<div id="openButtonOuter"> <div id="openButtonOuter">
</div> </div>
<div id="sideBarOuter"> <div id="sideBarOuter">
<aside id="sidebar"> <aside id="sidebar">
@@ -96,7 +95,6 @@
<footer> <footer>
&#169 Arne Zitting u. Hauke Kahrs &#169 Arne Zitting u. Hauke Kahrs
</footer> </footer>
<div id="info-panel"> <div id="info-panel">
<div id="info-panel-inner"> <div id="info-panel-inner">
<button class="sideBarButtons" id="closeInfoPanel" title="Info einklappen">>></button> <button class="sideBarButtons" id="closeInfoPanel" title="Info einklappen">>></button>
@@ -110,11 +108,9 @@
<p id="info-panel-text">Bitte wählen Sie eine Punktwolke aus.</p> <p id="info-panel-text">Bitte wählen Sie eine Punktwolke aus.</p>
</div> </div>
</div> </div>
<div id="info-button-outer"> <div id="info-button-outer">
</div> </div>
</main> </main>
<script src="./libs/jquery/jquery-3.1.1.min.js"></script> <script src="./libs/jquery/jquery-3.1.1.min.js"></script>
<script src="./libs/other/BinaryHeap.js"></script> <script src="./libs/other/BinaryHeap.js"></script>
<script src="./libs/tween/tween.min.js"></script> <script src="./libs/tween/tween.min.js"></script>
@@ -122,7 +118,6 @@
<script src="./libs/proj4/proj4.js"></script> <script src="./libs/proj4/proj4.js"></script>
<script src="./libs/potree/potree.js"></script> <script src="./libs/potree/potree.js"></script>
<script src="./libs/plasio/js/laslaz.js"></script> <script src="./libs/plasio/js/laslaz.js"></script>
<script type="module" src="/main.js"></script> <script type="module" src="/main.js"></script>
</body> </body>
</html> </html>
+23 -38
View File
@@ -1,9 +1,7 @@
import maplibregl from "maplibre-gl"; import maplibregl from "maplibre-gl";
import proj4 from "proj4"; import proj4 from "proj4";
import * as THREE from "three"; import * as THREE from "three";
// !!! NPM import
import { LidarControl } from "maplibre-gl-lidar"; import { LidarControl } from "maplibre-gl-lidar";
// CSS Styles importieren!
import "maplibre-gl/dist/maplibre-gl.css"; import "maplibre-gl/dist/maplibre-gl.css";
import "maplibre-gl-lidar/style.css"; import "maplibre-gl-lidar/style.css";
@@ -38,7 +36,6 @@ let currentPointcloudKey = null;
let lidarControl=null; let lidarControl=null;
var quality = 'medium'; var quality = 'medium';
//-------------------------LOGIK DECK.GL - aktuell beim Laden der Karte - hier rausnehmen------------------------------------------------------
// WICHTIG: Layer/Controls immer erst im 'load'-Event der Karte hinzufügen // WICHTIG: Layer/Controls immer erst im 'load'-Event der Karte hinzufügen
map.on('load', () => { map.on('load', () => {
@@ -71,7 +68,6 @@ viewer.setBackground("none");
viewer.orbitControls.enabled = false; viewer.orbitControls.enabled = false;
viewer.fpControls.enabled = false; viewer.fpControls.enabled = false;
viewer.deviceControls.enabled = false; viewer.deviceControls.enabled = false;
elRenderArea.style.display='none'; elRenderArea.style.display='none';
function resetLidarControl() { function resetLidarControl() {
@@ -132,6 +128,7 @@ function applyDeckGLSettings() {
try { try {
lidarControl.setPointSize(currentPointSize > 0 ? currentPointSize : 2); lidarControl.setPointSize(currentPointSize > 0 ? currentPointSize : 2);
lidarControl.setColorScheme(currentColorMode === 'rgb' ? 'rgb' : 'elevation'); lidarControl.setColorScheme(currentColorMode === 'rgb' ? 'rgb' : 'elevation');
lidarControl.setColormap('jet');
} catch(e) { console.warn("LidarControl API:", e); } } catch(e) { console.warn("LidarControl API:", e); }
} }
@@ -194,11 +191,10 @@ function loadInfoJSON() {
.then(data => { pointCloudInfo = data; }) .then(data => { pointCloudInfo = data; })
.catch(e => console.error("Fehler beim Laden der JSON:", e)); .catch(e => console.error("Fehler beim Laden der JSON:", e));
} }
// aktuell dargestellte Punktwolke
//------------------------lädt Punktwolke im Potree Format @hauke: entweder hier copc einbauen mit if else oder eigene Funktion dafür machen----------------------------- //------------------------lädt Punktwolke im Potree Format-----------------------------
function loadPointCloud(path) { function loadPointCloud(path) {
viewer.scene.view.yaw = 0; viewer.scene.view.yaw = 0;
viewer.scene.view.pitch = 0; viewer.scene.view.pitch = 0;
@@ -224,20 +220,25 @@ function loadPointCloud(path) {
// 1. Three.js zwingen, die Wolke sofort in der 3D-Welt zu platzieren // 1. Three.js zwingen, die Wolke sofort in der 3D-Welt zu platzieren
currentPointCloud.updateMatrixWorld(true); currentPointCloud.updateMatrixWorld(true);
// 2. POTREE WECKRUF: Zwinge den Viewer, sich intern zu dimensionieren. // 2. POTREE WECKRUF
// Das löst das Problem, dass Potree beim allerersten Aufruf die Kamera ignoriert.
viewer.update(viewer.clock.getDelta(), Number.MAX_VALUE); viewer.update(viewer.clock.getDelta(), Number.MAX_VALUE);
// --- HIER IST DIE KORREKTUR ---
// Erzwinge den aktuell ausgewählten Farbmodus (z.B. elevation)
// auf das frisch generierte Material der neuen Punktwolke!
applyColorMode();
// 3. Jetzt die Kamera berechnen und setzen // 3. Jetzt die Kamera berechnen und setzen
syncCamera(); syncCamera();
// 4. Ein zweites Mal synchronisieren, falls MapLibre im selben Frame das Canvas resized hat // 4. Ein zweites Mal synchronisieren
requestAnimationFrame(() => { requestAnimationFrame(() => {
syncCamera(); syncCamera();
}); });
}); });
} }
// Variable, um Endlosschleifen zu verhindern // Variable, um Endlosschleifen zu verhindern
let isSyncing = false; let isSyncing = false;
@@ -289,22 +290,14 @@ function syncCamera() {
isSyncing = false; isSyncing = false;
} }
// ==========================================
// DER REVOLUTIONÄRE SYNCHRONISATIONS-LOOP
// ==========================================
// Wir klinken uns direkt in den Browser-Zeichenzyklus von MapLibre ein.
// Jedes Mal, wenn MapLibre ein Frame anfordert, aktualisieren wir Potree DIREKT davor/dabei.
const originalRequestAnimationFrame = window.requestAnimationFrame; const originalRequestAnimationFrame = window.requestAnimationFrame;
const hookRenderLoop = () => { const hookRenderLoop = () => {
// Erzwinge die Kamerasynchronisation bei jedem Karten-Update // Erzwinge die Kamerasynchronisation bei jedem Karten-Update
syncCamera(); syncCamera();
}; };
// Verwende MapLibres internes Repaint-System, um absolut latenzfrei zu synchronisieren // Verwendet MapLibres internes Repaint-System, um absolut latenzfrei zu synchronisieren
map.on('movestart', () => { map.on('movestart', () => {
// Während der Interaktion zwingen wir MapLibre zu einem Dauer-Repaint,
// damit der Render-Loop durchgehend feuert
map.getCanvasContainer().style.cursor = 'grabbing'; map.getCanvasContainer().style.cursor = 'grabbing';
}); });
@@ -313,14 +306,7 @@ map.on('zoom', syncCamera);
map.on('move', syncCamera); map.on('move', syncCamera);
map.on('rotate', syncCamera); map.on('rotate', syncCamera);
map.on('pitch', syncCamera); map.on('pitch', syncCamera);
// Zusätzliche Absicherung für CSS/DOM-Verzögerungen:
// Das 'draw'-Event feuert tiefer im Inneren von MapLibre als 'render'
map.on('draw', syncCamera); map.on('draw', syncCamera);
// CSS-Fix für das Potree-Container-Element (wichtig gegen Mikroruckler)
// Stelle sicher, dass dein #potree_render_area im CSS folgende Attribute hat:
// pointer-events: none; (damit MapLibre die Maus-Events direkt und ohne Millisekunden-Verzögerung bekommt!)
elRenderArea.style.pointerEvents = "none"; elRenderArea.style.pointerEvents = "none";
map.getCanvas().style.pointerEvents = "auto"; map.getCanvas().style.pointerEvents = "auto";
@@ -487,6 +473,7 @@ document.querySelector('select[name="pointcloud"]').addEventListener('change', (
// Kartenausschnitt auf Ursprung zurücksetzen // Kartenausschnitt auf Ursprung zurücksetzen
document.getElementById("location").addEventListener("click", () => map.flyTo({center, zoom: 17})); document.getElementById("location").addEventListener("click", () => map.flyTo({center, zoom: 17}));
document.getElementById("pointSizeSlider").oninput = function() { document.getElementById("pointSizeSlider").oninput = function() {
//viewer.setMinNodeSize(this.value); //viewer.setMinNodeSize(this.value);
currentPointSize = Number(this.value); currentPointSize = Number(this.value);
@@ -497,6 +484,7 @@ if (currentRenderer === 'potree') {
} }
}; };
const closeButton = document.getElementById("closeSideBarButton"); const closeButton = document.getElementById("closeSideBarButton");
const sidebar = document.getElementById("sidebar"); const sidebar = document.getElementById("sidebar");
const openOuter = document.getElementById("openButtonOuter"); const openOuter = document.getElementById("openButtonOuter");
@@ -514,6 +502,7 @@ if (closeButton) {
}); });
} }
document.querySelectorAll('.qualityButtons').forEach(btn => { document.querySelectorAll('.qualityButtons').forEach(btn => {
btn.addEventListener('click', () => { btn.addEventListener('click', () => {
quality = btn.id; quality = btn.id;
@@ -543,20 +532,7 @@ map.once('idle', () => {
}); });
// Falls du beim Start direkt eine Standard-Punktwolke lädst,
// stelle sicher, dass das Dropdown nach dem ersten stabilen Frame getriggert wird:
/*map.once('load', () => {
const selectBox = document.querySelector('select[name="pointcloud"]');
if (selectBox && selectBox.value) {
loadPointCloud(getPointCloudFiles()[selectBox.value]);
}*/
// Informationen über die Punktwolken zentral in einer JSON-Datei
//const pointCloudInfoFile = "info.json";
let pointCloudInfo = {}; let pointCloudInfo = {};
const infoPanel = document.getElementById("info-panel"); const infoPanel = document.getElementById("info-panel");
const infoPanelTitle = document.getElementById("info-panel-title"); const infoPanelTitle = document.getElementById("info-panel-title");
const infoPanelText = document.getElementById("info-panel-text"); const infoPanelText = document.getElementById("info-panel-text");
@@ -565,6 +541,7 @@ const closeInfoPanel = document.getElementById("closeInfoPanel");
let currentImageIndex = 0; let currentImageIndex = 0;
function updateInfoPanel() { function updateInfoPanel() {
const key = document.querySelector('select[name="pointcloud"]').value; const key = document.querySelector('select[name="pointcloud"]').value;
@@ -584,6 +561,7 @@ function updateInfoPanel() {
} }
} }
function updateImage(info) { function updateImage(info) {
const img = document.getElementById("info-panel-image"); const img = document.getElementById("info-panel-image");
const nav = document.getElementById("info-image-nav"); const nav = document.getElementById("info-image-nav");
@@ -600,6 +578,7 @@ function updateImage(info) {
} }
} }
document.getElementById("info-img-prev").addEventListener("click", () => { document.getElementById("info-img-prev").addEventListener("click", () => {
const key = document.querySelector('select[name="pointcloud"]').value; const key = document.querySelector('select[name="pointcloud"]').value;
const info = pointCloudInfo[key]; const info = pointCloudInfo[key];
@@ -608,6 +587,7 @@ document.getElementById("info-img-prev").addEventListener("click", () => {
updateImage(info); updateImage(info);
}); });
document.getElementById("info-img-next").addEventListener("click", () => { document.getElementById("info-img-next").addEventListener("click", () => {
const key = document.querySelector('select[name="pointcloud"]').value; const key = document.querySelector('select[name="pointcloud"]').value;
const info = pointCloudInfo[key]; const info = pointCloudInfo[key];
@@ -616,20 +596,25 @@ document.getElementById("info-img-next").addEventListener("click", () => {
updateImage(info); updateImage(info);
}); });
openInfoPanel.addEventListener("click", () => { openInfoPanel.addEventListener("click", () => {
infoPanel.classList.add("open"); infoPanel.classList.add("open");
//openInfoPanel.style.display = "none"; //openInfoPanel.style.display = "none";
}); });
closeInfoPanel.addEventListener("click", () => { closeInfoPanel.addEventListener("click", () => {
infoPanel.classList.remove("open"); infoPanel.classList.remove("open");
openInfoPanel.style.display = "flex"; openInfoPanel.style.display = "flex";
}); });
// Panel aktualisieren wenn Punktwolke gewechselt wird // Panel aktualisieren wenn Punktwolke gewechselt wird
document.querySelector('select[name="pointcloud"]').addEventListener("change", () => { document.querySelector('select[name="pointcloud"]').addEventListener("change", () => {
updateInfoPanel(); updateInfoPanel();
}); });
document.getElementById('rendererToggle').addEventListener('click', function() { document.getElementById('rendererToggle').addEventListener('click', function() {
const next = currentRenderer === 'deckgl' ? 'potree' : 'deckgl'; const next = currentRenderer === 'deckgl' ? 'potree' : 'deckgl';
switchRenderer(next); switchRenderer(next);
+11 -12
View File
@@ -3,8 +3,6 @@ html, body {
margin: 0; margin: 0;
} }
body{ body{
margin:0; margin:0;
overflow:hidden; overflow:hidden;
@@ -201,7 +199,6 @@ select{
margin-bottom: 10px; margin-bottom: 10px;
} }
#disable.active-state { #disable.active-state {
background: background:
linear-gradient( linear-gradient(
@@ -229,13 +226,11 @@ select:focus{
box-shadow:0 0 0 4px rgba(37,99,235,0.15), 0 8px 24px rgba(0,0,0,0.12); box-shadow:0 0 0 4px rgba(37,99,235,0.15), 0 8px 24px rgba(0,0,0,0.12);
} }
#disable:hover{ #disable:hover{
transform:translateY(-1px); transform:translateY(-1px);
box-shadow: 0 6px 18px rgba(0,0,0,0.12); box-shadow: 0 6px 18px rgba(0,0,0,0.12);
} }
*{ *{
transition: transition:
background 0.2s, background 0.2s,
@@ -400,7 +395,7 @@ position: absolute;
color: #ffffff; color: #ffffff;
} }
#potree_render_area { #potree_render_area {
pointer-events: none; pointer-events: none;
} }
@@ -427,12 +422,20 @@ position: absolute;
} }
#rendererToggle[data-active="deckgl"] { #rendererToggle[data-active="deckgl"] {
background: linear-gradient(135deg, rgba(18,77,216,0.92) 10%, rgba(13,61,175,0.92) 60%, rgba(6,45,135,0.92) 100%); background: linear-gradient(
135deg,
rgba(18,77,216,0.92) 10%,
rgba(13,61,175,0.92) 60%,
rgba(6,45,135,0.92) 100%);
color: #ffffff; color: #ffffff;
} }
#rendererToggle[data-active="potree"] { #rendererToggle[data-active="potree"] {
background: linear-gradient(135deg, rgba(22,163,74,0.92) 10%, rgba(15,118,54,0.92) 60%, rgba(6,78,32,0.92) 100%); background: linear-gradient(
135deg,
rgba(22,163,74,0.92) 10%,
rgba(15,118,54,0.92) 60%,
rgba(6,78,32,0.92) 100%);
color: #ffffff; color: #ffffff;
} }
@@ -552,14 +555,10 @@ position: absolute;
color: #555; color: #555;
} }
/* Blendet das Icon selbst aus */
.lidar-control-icon { .lidar-control-icon {
display: none !important; display: none !important;
} }
/* Findet den MapLibre-Button, der das Lidar-Icon beinhaltet,
und versteckt den kompletten Button (inklusive Rahmen und Hintergrund) */
.maplibregl-ctrl:has(.lidar-control-icon), .maplibregl-ctrl:has(.lidar-control-icon),
.maplibregl-ctrl-group:has(.lidar-control-icon), .maplibregl-ctrl-group:has(.lidar-control-icon),
button:has(.lidar-control-icon) { button:has(.lidar-control-icon) {