diff --git a/index.html b/index.html
index 2a32f57..ecb6ebb 100644
--- a/index.html
+++ b/index.html
@@ -65,15 +65,18 @@
-
-
Klein
Groß
-
-
+
+
+
+
diff --git a/main.js b/main.js
index 9ccf90c..a2af2c1 100644
--- a/main.js
+++ b/main.js
@@ -29,9 +29,17 @@ map.addControl(new maplibregl.NavigationControl({
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------------------------------------------------------
-let lidarControl;
+
// WICHTIG: Layer/Controls immer erst im 'load'-Event der Karte hinzufügen
map.on('load', () => {
lidarControl = new LidarControl({
@@ -42,30 +50,51 @@ map.on('load', () => {
pickable: false
});
- //map.addControl(lidarControl, 'top-right');
- lidarControl.onAdd(map);
+ map.addControl(lidarControl, 'top-right');
+ //lidarControl.onAdd(map);
// 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--------------------------
-var pointBudget = document.getElementById("pointSlider").value; // wahrscheinlich noch rausschmeißen
var pointSize = document.getElementById("pointSizeSlider").value;
const elRenderArea = document.getElementById("potree_render_area");
const viewer = new Potree.Viewer(elRenderArea, {noDragAndDrop: true});
viewer.setEDLEnabled(false);
viewer.setFOV(60);
-viewer.setPointBudget(pointBudget);
viewer.setMinNodeSize(pointSize);
viewer.setBackground("none");
viewer.orbitControls.enabled = false;
viewer.fpControls.enabled = false;
viewer.deviceControls.enabled = false;
-// Standardwert der Punktwolkenqualität
-var quality = 'medium';
+elRenderArea.style.display='none';
+
+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
function getPointCloudFilesPOTREE() {
@@ -80,14 +109,85 @@ function getPointCloudFilesPOTREE() {
function getPointCloudFilesCOPC() {
return {
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`,
- third: `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/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
-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-----------------------------
@@ -138,7 +238,7 @@ let isSyncing = false;
*/
function syncCamera() {
- if (!currentPointCloud || isSyncing) return;
+ if (!currentPointCloud || isSyncing || currentRenderer!== 'potree') return;
isSyncing = true;
const transform = map.transform;
@@ -341,8 +441,9 @@ function changeBaseMap(newMap) {
document.querySelector('#disable').addEventListener('click', function() {
isVisible = !isVisible;
- if (currentPointCloud)
- currentPointCloud.visible = isVisible;
+ //if (currentPointCloud)
+ // currentPointCloud.visible = isVisible;
+ applyVisibility();
if(isVisible) {
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
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
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() {
- 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");
@@ -409,7 +509,8 @@ if (closeButton) {
document.querySelectorAll('.qualityButtons').forEach(btn => {
btn.addEventListener('click', () => {
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'));
btn.classList.add('active');
});
@@ -418,32 +519,12 @@ document.querySelectorAll('.qualityButtons').forEach(btn => {
document.querySelectorAll('.colorButtons').forEach(btn => {
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'));
btn.classList.add('active');
-
- let value = btn.id;
- 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();
+ currentColorMode = btn.id;
+ applyColorMode();
});
});
@@ -456,25 +537,17 @@ 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', () => {
+/*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";
+//const pointCloudInfoFile = "info.json";
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 infoPanelTitle = document.getElementById("info-panel-title");
@@ -549,5 +622,8 @@ closeInfoPanel.addEventListener("click", () => {
document.querySelector('select[name="pointcloud"]').addEventListener("change", () => {
updateInfoPanel();
});
+document.getElementById('rendererToggle').addEventListener('click', function() {
+ const next = currentRenderer === 'deckgl' ? 'potree' : 'deckgl';
+ switchRenderer(next);
});
diff --git a/style.css b/style.css
index 913daa0..5b9776b 100644
--- a/style.css
+++ b/style.css
@@ -251,7 +251,7 @@ margin:0;
margin-bottom: -2px;
}
-#pointSlider, #pointSizeSlider{
+#pointSizeSlider{
width: 100%;
margin: 0;
padding: 0;
@@ -405,14 +405,47 @@ position: absolute;
transform: translateY(-50%);
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 {
margin-top: 12px;
border: none;
border-radius: 14px;
- width: auto;
+ width: 100%;
padding: 10px 16px;
- font-size: 17px;
+ font-size: 14px;
font-weight: 500;
cursor: pointer;
background: rgba(255,255,255,0.9);
@@ -429,6 +462,12 @@ position: absolute;
transform: translateY(-1px);
}
+#openInfoPanel img {
+ width: 16px;
+ height: 16px;
+ object-fit: contain;
+}
+
#info-panel {
display: none;
position: absolute;