Deckgl version fertiggestellt. Switch zwischen deckgl und Potree möglich. Pointbudget entfernt

This commit is contained in:
2026-06-16 13:15:38 +02:00
parent e26ebc2bf0
commit 7e063db32e
3 changed files with 187 additions and 69 deletions
+7 -4
View File
@@ -65,15 +65,18 @@
<button class="colorButtons active" id="rgb">RGB</button> <button class="colorButtons active" id="rgb">RGB</button>
<button class="colorButtons" id="height">höhencodiert</button> <button class="colorButtons" id="height">höhencodiert</button>
</div> </div>
<p class="sideBarText" id="pointSliderValue"></p>
<input id="pointSlider" type="range" min="500000" max="10000000" value="3000000">
<p class="sideBarText" id="pointSizeSliderValue">Punktgröße</p> <p class="sideBarText" id="pointSizeSliderValue">Punktgröße</p>
<div class="slider-labels"> <div class="slider-labels">
<span>Klein</span> <span>Klein</span>
<span>Groß</span> <span>Groß</span>
</div> </div>
<input id="pointSizeSlider" type="range" min="0" max="1000" value="0" step="1"> <input id="pointSizeSlider" type="range" min="1" max="10" value="2" step="1">
<button id="openInfoPanel" title="Informationen zur Punktwolke"><img id="location" title="Standort zurücksetzen" src="info.png" />Informationen</button> <p class="sideBarText">Renderer</p>
<button id="rendererToggle" data-active="deckgl" title="Renderer wechseln">
<span id="rendererLabel">Renderer: Deck.gl</span>
<span id="rendererIcon"></span>
</button>
<button id="openInfoPanel" title="Informationen zur Punktwolke"><img src="info.png"/>Informationen</button>
<div class="logos"> <div class="logos">
<a href="http://www.jade-hs.de"> <a href="http://www.jade-hs.de">
<img id="logoJadeHs" src="logoJadeHs.png" /> <img id="logoJadeHs" src="logoJadeHs.png" />
+137 -61
View File
@@ -29,9 +29,17 @@ map.addControl(new maplibregl.NavigationControl({
showCompass: true showCompass: true
})); }));
let currentPointCloud = null;
let isVisible = true;
let currentRenderer='deckgl';
let currentColorMode='rgb';
let currentPointSize=Number(document.getElementById("pointSizeSlider").value);
let currentPointcloudKey = null;
let lidarControl=null;
var quality = 'medium';
//-------------------------LOGIK DECK.GL - aktuell beim Laden der Karte - hier rausnehmen------------------------------------------------------ //-------------------------LOGIK DECK.GL - aktuell beim Laden der Karte - hier rausnehmen------------------------------------------------------
let lidarControl;
// 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', () => {
lidarControl = new LidarControl({ lidarControl = new LidarControl({
@@ -42,30 +50,51 @@ map.on('load', () => {
pickable: false pickable: false
}); });
//map.addControl(lidarControl, 'top-right'); map.addControl(lidarControl, 'top-right');
lidarControl.onAdd(map); //lidarControl.onAdd(map);
// COPC-Datei laden // COPC-Datei laden
lidarControl.loadPointCloudStreaming('http://ar2350.web-01.fbbgg.hs-woe.de/copc%20Daten/sp3_low.copc.laz') const selectBox=document.querySelector('select[name="pointcloud"]');
if (selectBox && selectBox.value){
currentPointcloudKey=selectBox.value;
loadCurrentPointCloud();
}
loadInfoJSON();
//lidarControl.loadPointCloudStreaming('http://ar2350.web-01.fbbgg.hs-woe.de/copc%20Daten/sp3_low.copc.laz')
}); });
//---------------Potree Eigenschaften-------------------------- //---------------Potree Eigenschaften--------------------------
var pointBudget = document.getElementById("pointSlider").value; // wahrscheinlich noch rausschmeißen
var pointSize = document.getElementById("pointSizeSlider").value; var pointSize = document.getElementById("pointSizeSlider").value;
const elRenderArea = document.getElementById("potree_render_area"); const elRenderArea = document.getElementById("potree_render_area");
const viewer = new Potree.Viewer(elRenderArea, {noDragAndDrop: true}); const viewer = new Potree.Viewer(elRenderArea, {noDragAndDrop: true});
viewer.setEDLEnabled(false); viewer.setEDLEnabled(false);
viewer.setFOV(60); viewer.setFOV(60);
viewer.setPointBudget(pointBudget);
viewer.setMinNodeSize(pointSize); viewer.setMinNodeSize(pointSize);
viewer.setBackground("none"); 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;
// Standardwert der Punktwolkenqualität elRenderArea.style.display='none';
var quality = 'medium';
function resetLidarControl() {
if (!lidarControl) return;
try {
map.removeControl(lidarControl);
} catch(e) {}
lidarControl = null;
lidarControl = new LidarControl({
title: 'Mein LiDAR-Viewer',
collapsed: false,
pointSize: currentPointSize > 0 ? currentPointSize : 2,
colorScheme: currentColorMode === 'rgb' ? 'rgb' : 'elevation',
pickable: false
});
map.addControl(lidarControl, 'top-right');
}
// Punktwolkendaten im Potree-Format // Punktwolkendaten im Potree-Format
function getPointCloudFilesPOTREE() { function getPointCloudFilesPOTREE() {
@@ -80,14 +109,85 @@ function getPointCloudFilesPOTREE() {
function getPointCloudFilesCOPC() { function getPointCloudFilesCOPC() {
return { return {
first: `http://ar2350.web-01.fbbgg.hs-woe.de/copc%20Daten/sp1_${quality}.copc.laz`, first: `http://ar2350.web-01.fbbgg.hs-woe.de/copc%20Daten/sp1_${quality}.copc.laz`,
second: `http://ar2350.web-01.fbbgg.hs-woe.de/copc%20Daten/sp1_${quality}.copc.laz`, second: `http://ar2350.web-01.fbbgg.hs-woe.de/copc%20Daten/sp2_${quality}.copc.laz`,
third: `http://ar2350.web-01.fbbgg.hs-woe.de/copc%20Daten/sp1_${quality}.copc.laz`, third: `http://ar2350.web-01.fbbgg.hs-woe.de/copc%20Daten/sp3_${quality}.copc.laz`,
}; };
} }
function loadCurrentPointCloud() {
if (!currentPointcloudKey) return;
if (currentRenderer === 'deckgl') {
loadDeckGL(getPointCloudFilesCOPC()[currentPointcloudKey]);
} else {
loadPointCloud(getPointCloudFilesPOTREE()[currentPointcloudKey]);
}
}
function loadDeckGL(path) {
if (!lidarControl || !path) return;
resetLidarControl();
lidarControl.loadPointCloudStreaming(path);
setTimeout(() => applyDeckGLSettings(), 500);
}
function applyDeckGLSettings() {
if (!lidarControl) return;
try {
lidarControl.setPointSize(currentPointSize > 0 ? currentPointSize : 2);
lidarControl.setColorScheme(currentColorMode === 'rgb' ? 'rgb' : 'elevation');
} catch(e) { console.warn("LidarControl API:", e); }
}
function switchRenderer(renderer) {
currentRenderer = renderer;
if (renderer === 'deckgl') {
elRenderArea.style.display = 'none';
if (currentPointCloud) currentPointCloud.visible = false;
if (lidarControl && currentPointcloudKey) loadDeckGL(getPointCloudFilesCOPC()[currentPointcloudKey]);
document.getElementById('rendererToggle').dataset.active = 'deckgl';
document.getElementById('rendererLabel').textContent = 'Renderer: Deck.gl';
} else {
resetLidarControl();
elRenderArea.style.display = 'block';
if (currentPointcloudKey) loadPointCloud(getPointCloudFilesPOTREE()[currentPointcloudKey]);
document.getElementById('rendererToggle').dataset.active = 'potree';
document.getElementById('rendererLabel').textContent = 'Renderer: Potree';
}
applyVisibility();
}
function applyVisibility() {
if (currentRenderer === 'potree' && currentPointCloud) {
currentPointCloud.visible = isVisible;
}
if (currentRenderer === 'deckgl' && lidarControl) {
try { lidarControl.setVisible(isVisible); } catch(e) { console.warn("setVisible:", e); }
}
}
function applyColorModePotree() {
if (!currentPointCloud) return;
let mat = currentPointCloud.material;
mat.activeAttributeName = currentColorMode === 'rgb' ? "rgba" : "elevation";
viewer.renderer.resetState();
viewer.render();
map.triggerRepaint();
}
function applyColorMode() {
if (currentRenderer === 'potree') { applyColorModePotree(); }
else { applyDeckGLSettings(); }
}
function loadInfoJSON() {
fetch("info.json")
.then(r => r.json())
.then(data => { pointCloudInfo = data; })
.catch(e => console.error("Fehler beim Laden der JSON:", e));
}
// aktuell dargestellte Punktwolke // aktuell dargestellte Punktwolke
let currentPointCloud = null;
let isVisible = true;
//------------------------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 @hauke: entweder hier copc einbauen mit if else oder eigene Funktion dafür machen-----------------------------
@@ -138,7 +238,7 @@ let isSyncing = false;
*/ */
function syncCamera() { function syncCamera() {
if (!currentPointCloud || isSyncing) return; if (!currentPointCloud || isSyncing || currentRenderer!== 'potree') return;
isSyncing = true; isSyncing = true;
const transform = map.transform; const transform = map.transform;
@@ -341,8 +441,9 @@ function changeBaseMap(newMap) {
document.querySelector('#disable').addEventListener('click', function() { document.querySelector('#disable').addEventListener('click', function() {
isVisible = !isVisible; isVisible = !isVisible;
if (currentPointCloud) //if (currentPointCloud)
currentPointCloud.visible = isVisible; // currentPointCloud.visible = isVisible;
applyVisibility();
if(isVisible) { if(isVisible) {
this.textContent = "Punktwolke ausblenden"; this.textContent = "Punktwolke ausblenden";
@@ -369,24 +470,23 @@ document.querySelector('select[name="basemap"]').addEventListener('change', (e)
// Punktwolke austauschen, wenn anderes Element im DropDown gewählt wird // Punktwolke austauschen, wenn anderes Element im DropDown gewählt wird
document.querySelector('select[name="pointcloud"]').addEventListener('change', (e) => { document.querySelector('select[name="pointcloud"]').addEventListener('change', (e) => {
loadPointCloud(getPointCloudFilesPOTREE()[e.target.value]); //loadPointCloud(getPointCloudFilesPOTREE()[e.target.value]);
currentPointcloudKey = e.target.value;
loadCurrentPointCloud();
}); });
// 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}));
var pointCountSlider = document.getElementById("pointSlider");
var pointCountOutput = document.getElementById("pointSliderValue");
pointCountOutput.innerHTML = "Dargestellte Punkte: " + Number(pointCountSlider.value).toLocaleString();
pointCountSlider.oninput = function() {
pointCountOutput.innerHTML = "Dargestellte Punkte: " + Number(this.value).toLocaleString('de-DE');
viewer.setPointBudget(this.value);
};
document.getElementById("pointSizeSlider").oninput = function() { document.getElementById("pointSizeSlider").oninput = function() {
viewer.setMinNodeSize(this.value); //viewer.setMinNodeSize(this.value);
currentPointSize = Number(this.value);
if (currentRenderer === 'potree') {
viewer.setMinNodeSize(currentPointSize);
} else if (lidarControl) {
try { lidarControl.setPointSize(currentPointSize); } catch(e) {}
}
}; };
const closeButton = document.getElementById("closeSideBarButton"); const closeButton = document.getElementById("closeSideBarButton");
@@ -409,7 +509,8 @@ if (closeButton) {
document.querySelectorAll('.qualityButtons').forEach(btn => { document.querySelectorAll('.qualityButtons').forEach(btn => {
btn.addEventListener('click', () => { btn.addEventListener('click', () => {
quality = btn.id; quality = btn.id;
if (currentPointCloud) loadPointCloud(getPointCloudFiles()[document.getElementById("pointcloud").value]); //if (currentPointCloud) loadPointCloud(getPointCloudFiles()[document.getElementById("pointcloud").value]);
if (currentPointcloudKey) loadCurrentPointCloud();
document.querySelectorAll('.qualityButtons').forEach(b => b.classList.remove('active')); document.querySelectorAll('.qualityButtons').forEach(b => b.classList.remove('active'));
btn.classList.add('active'); btn.classList.add('active');
}); });
@@ -418,32 +519,12 @@ document.querySelectorAll('.qualityButtons').forEach(btn => {
document.querySelectorAll('.colorButtons').forEach(btn => { document.querySelectorAll('.colorButtons').forEach(btn => {
btn.addEventListener('click', () => { btn.addEventListener('click', () => {
if (!currentPointCloud) return; // Abbrechen, falls noch keine Wolke geladen ist //if (!currentPointCloud) return; // Abbrechen, falls noch keine Wolke geladen ist
document.querySelectorAll('.colorButtons').forEach(b => b.classList.remove('active')); document.querySelectorAll('.colorButtons').forEach(b => b.classList.remove('active'));
btn.classList.add('active'); btn.classList.add('active');
currentColorMode = btn.id;
let value = btn.id; applyColorMode();
console.log("WERT: " + value);
// Greife immer das aktuelle Material ab
let currentMaterial = currentPointCloud.material;
if (value === "rgb") {
// "rgba" stellt die echten RGB-Farben der Punkte dar
currentMaterial.activeAttributeName = "rgba";
} else if (value === "height") {
// "elevation" wechselt auf die Einfärbung nach Höhe (Z-Wert)
currentMaterial.activeAttributeName = "elevation";
}
// POTREE RE-RENDER TRICK:
// Potree muss wissen, dass sich das Material verändert hat, damit die Shader neu geladen werden.
viewer.renderer.resetState();
viewer.render();
// MapLibre ebenfalls Bescheid geben, dass sich die Overlays geändert haben
map.triggerRepaint();
}); });
}); });
@@ -456,25 +537,17 @@ map.once('idle', () => {
// Falls du beim Start direkt eine Standard-Punktwolke lädst, // Falls du beim Start direkt eine Standard-Punktwolke lädst,
// stelle sicher, dass das Dropdown nach dem ersten stabilen Frame getriggert wird: // stelle sicher, dass das Dropdown nach dem ersten stabilen Frame getriggert wird:
map.once('load', () => { /*map.once('load', () => {
const selectBox = document.querySelector('select[name="pointcloud"]'); const selectBox = document.querySelector('select[name="pointcloud"]');
if (selectBox && selectBox.value) { if (selectBox && selectBox.value) {
loadPointCloud(getPointCloudFiles()[selectBox.value]); loadPointCloud(getPointCloudFiles()[selectBox.value]);
} }*/
// Informationen über die Punktwolken zentral in einer JSON-Datei // Informationen über die Punktwolken zentral in einer JSON-Datei
const pointCloudInfoFile = "info.json"; //const pointCloudInfoFile = "info.json";
let pointCloudInfo = {}; let pointCloudInfo = {};
// die JSON-Datei laden
fetch(pointCloudInfoFile)
.then(response => response.json())
.then(data => {
pointCloudInfo = data;
})
.catch(error => console.error("Fehler beim Laden der JSON:", error));
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");
@@ -549,5 +622,8 @@ closeInfoPanel.addEventListener("click", () => {
document.querySelector('select[name="pointcloud"]').addEventListener("change", () => { document.querySelector('select[name="pointcloud"]').addEventListener("change", () => {
updateInfoPanel(); updateInfoPanel();
}); });
document.getElementById('rendererToggle').addEventListener('click', function() {
const next = currentRenderer === 'deckgl' ? 'potree' : 'deckgl';
switchRenderer(next);
}); });
+42 -3
View File
@@ -251,7 +251,7 @@ margin:0;
margin-bottom: -2px; margin-bottom: -2px;
} }
#pointSlider, #pointSizeSlider{ #pointSizeSlider{
width: 100%; width: 100%;
margin: 0; margin: 0;
padding: 0; padding: 0;
@@ -405,14 +405,47 @@ position: absolute;
transform: translateY(-50%); transform: translateY(-50%);
z-index: 30; z-index: 30;
} }
#rendererToggle {
width: 100%;
padding: 10px 16px;
border: none;
border-radius: 14px;
font-size: 13px;
font-weight: 500;
cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 0 5px 10px rgba(0,0,0,0.278);
transition: 0.2s;
}
#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%);
color: #ffffff;
}
#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%);
color: #ffffff;
}
#rendererToggle:hover {
transform: translateY(-1px);
box-shadow: 0 6px 18px rgba(0,0,0,0.12);
}
#rendererIcon {
font-size: 16px;
}
#openInfoPanel { #openInfoPanel {
margin-top: 12px; margin-top: 12px;
border: none; border: none;
border-radius: 14px; border-radius: 14px;
width: auto; width: 100%;
padding: 10px 16px; padding: 10px 16px;
font-size: 17px; font-size: 14px;
font-weight: 500; font-weight: 500;
cursor: pointer; cursor: pointer;
background: rgba(255,255,255,0.9); background: rgba(255,255,255,0.9);
@@ -429,6 +462,12 @@ position: absolute;
transform: translateY(-1px); transform: translateY(-1px);
} }
#openInfoPanel img {
width: 16px;
height: 16px;
object-fit: contain;
}
#info-panel { #info-panel {
display: none; display: none;
position: absolute; position: absolute;