From 14ed0699e92deda291912d364876c1b181bfb8ed Mon Sep 17 00:00:00 2001 From: Hauke Kahrs Date: Sat, 6 Jun 2026 10:54:45 +0200 Subject: [PATCH] custom layer test --- main.js | 276 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 275 insertions(+), 1 deletion(-) diff --git a/main.js b/main.js index a6e6066..f498747 100644 --- a/main.js +++ b/main.js @@ -1,4 +1,4 @@ -import maplibregl from "maplibre-gl"; +/*import maplibregl from "maplibre-gl"; import proj4 from "proj4"; import * as THREE from "three"; console.log(THREE); @@ -433,4 +433,278 @@ colorButtons.forEach(button => { }); +});*/ +import maplibregl from "maplibre-gl"; +import proj4 from "proj4"; +import * as THREE from "three"; + +proj4.defs( + "EPSG:25832", + "+proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs" +); + +const center = [9.209116842757239, 52.26520546238239]; + +const map = new maplibregl.Map({ + container: "map", + style: "https://tiles.openfreemap.org/styles/bright", + center: center, + zoom: 17, + maxZoom: 24, + canvasContextAttributes: { antialias: true }, +}); + +map.addControl( + new maplibregl.NavigationControl({ + visualizePitch: true, + showZoom: true, + showCompass: true, + }) +); + +const coordinatesDiv = document.getElementById("coordinates"); +map.on("mousemove", (e) => { + coordinatesDiv.innerHTML = `Lon: ${e.lngLat.lng.toFixed(5)}° | Lat: ${e.lngLat.lat.toFixed(5)}°`; +}); + +var pointBudget = document.getElementById("pointSlider").value; +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; + +const originLngLat = { lng: center[0], lat: center[1] }; +const originMercator = maplibregl.MercatorCoordinate.fromLngLat(originLngLat, 0); +const metersToMercator = originMercator.meterInMercatorCoordinateUnits(); + +const potreeLayer = { + id: "potree-pointcloud", + type: "custom", + renderingMode: "3d", + + onAdd(map, gl) { + this.map = map; + this.gl = gl; + this.camera = new THREE.Camera(); + this.renderer = new THREE.WebGLRenderer({ + canvas: map.getCanvas(), + context: gl, + antialias: true, + }); + this.renderer.autoClear = false; + this.scene = new THREE.Scene(); + }, + + render(gl, args) { + if (!currentPointCloud) return; + + const m = new THREE.Matrix4().fromArray( + args.defaultProjectionData.mainMatrix + ); + + const [originX, originY] = proj4("EPSG:4326", "EPSG:25832", [ + center[0], + center[1], + ]); + + const l = new THREE.Matrix4() + .makeTranslation( + -originX * metersToMercator + originMercator.x, + originY * metersToMercator - originMercator.y, + 0 + ) + .premultiply( + new THREE.Matrix4().makeScale( + metersToMercator, + -metersToMercator, + metersToMercator + ) + ); + + this.camera.projectionMatrix = m.multiply(l); + + this.renderer.resetState(); + this.renderer.render(viewer.scene.scene, this.camera); + this.map.triggerRepaint(); + }, +}; + +map.on("style.load", () => { + map.addLayer(potreeLayer); +}); + +var quality = "medium"; +let currentPointCloud = null; +let isVisible = true; + +function getPointCloudFiles() { + return { + first: `http://ar2350.web-01.fbbgg.hs-woe.de/Punktwolken%20konvertiert%20potree%20Format/sp1_${quality}/metadata.json`, + second: `http://ar2350.web-01.fbbgg.hs-woe.de/Punktwolken%20konvertiert%20potree%20Format/sp2_${quality}/metadata.json`, + third: `http://ar2350.web-01.fbbgg.hs-woe.de/Punktwolken%20konvertiert%20potree%20Format/sp3_${quality}/metadata.json`, + }; +} + +function loadPointCloud(path) { + if (currentPointCloud) { + const index = viewer.scene.pointclouds.indexOf(currentPointCloud); + if (index !== -1) viewer.scene.pointclouds.splice(index, 1); + if (currentPointCloud.parent) currentPointCloud.parent.remove(currentPointCloud); + currentPointCloud = null; + map.triggerRepaint(); + } + + if (!path || !isVisible) return; + + Potree.loadPointCloud(path, "punktwolke", function (e) { + currentPointCloud = e.pointcloud; + viewer.scene.addPointCloud(currentPointCloud); + + let material = currentPointCloud.material; + material.size = 1; + material.pointSizeType = Potree.PointSizeType.ADAPTIVE; + + map.triggerRepaint(); + }); +} + +function changeBaseMap(newMap) { + var basemapStyle; + switch (newMap) { + case "openfree_dark": + basemapStyle = "https://tiles.openfreemap.org/styles/dark"; + break; + case "openfree_bright": + basemapStyle = "https://tiles.openfreemap.org/styles/bright"; + break; + case "openfree_liberty": + basemapStyle = "https://tiles.openfreemap.org/styles/liberty"; + break; + case "google_satellite": + basemapStyle = { + version: 8, + sources: { + "raster-tiles": { + type: "raster", + tiles: ["https://api.maptiler.com/tiles/satellite-v2/{z}/{x}/{y}.jpg?key=6mG881AthmTTWyLvFyjH"], + tileSize: 256, + attribution: "© MapTiler", + }, + }, + layers: [{ id: "satellite-layer", type: "raster", source: "raster-tiles" }], + }; + break; + case "terrain": + basemapStyle = { + version: 8, + sources: { + topo: { type: "raster", url: "https://api.maptiler.com/maps/topo-v4/tiles.json?key=6mG881AthmTTWyLvFyjH", tileSize: 256 }, + terrainSource: { type: "raster-dem", url: "https://tiles.mapterhorn.com/tilejson.json" }, + hillshadeSource: { type: "raster-dem", url: "https://tiles.mapterhorn.com/tilejson.json" }, + }, + layers: [ + { id: "topo", type: "raster", source: "topo" }, + { id: "hills", type: "hillshade", source: "hillshadeSource", layout: { visibility: "visible" }, paint: { "hillshade-shadow-color": "#473B24" } }, + ], + terrain: { source: "terrainSource", exaggeration: 1 }, + sky: {}, + }; + break; + case "satellite_terrain": + basemapStyle = { + version: 8, + sources: { + "raster-tiles": { type: "raster", tiles: ["https://api.maptiler.com/tiles/satellite-v2/{z}/{x}/{y}.jpg?key=6mG881AthmTTWyLvFyjH"], tileSize: 256, attribution: "© MapTiler" }, + terrainSource: { type: "raster-dem", url: "https://tiles.mapterhorn.com/tilejson.json" }, + hillshadeSource: { type: "raster-dem", url: "https://tiles.mapterhorn.com/tilejson.json" }, + }, + layers: [ + { id: "raster-tiles", type: "raster", source: "raster-tiles" }, + { id: "hills", type: "hillshade", source: "hillshadeSource", layout: { visibility: "visible" }, paint: { "hillshade-shadow-color": "#473B24" } }, + ], + terrain: { source: "terrainSource", exaggeration: 1 }, + sky: {}, + }; + break; + } + map.setStyle(basemapStyle); + map.once("style.load", () => { + map.addLayer(potreeLayer); + }); +} + +document.querySelector("#disable").addEventListener("click", function () { + isVisible = !isVisible; + if (currentPointCloud) currentPointCloud.visible = isVisible; + this.textContent = isVisible ? "Punktwolke ausblenden" : "Punktwolke anzeigen"; +}); + +document.querySelector('select[name="basemap"]').addEventListener("change", (e) => { + changeBaseMap(e.target.value); +}); + +document.querySelector('select[name="pointcloud"]').addEventListener("change", (e) => { + const files = getPointCloudFiles(); + loadPointCloud(files[e.target.value]); +}); + +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); +}; + +const closeButton = document.getElementById("closeSideBarButton"); +const sidebar = document.getElementById("sidebar"); +const openOuter = document.getElementById("openButtonOuter"); +if (closeButton) { + closeButton.addEventListener("click", () => { + const rect = closeButton.getBoundingClientRect(); + sidebar.style.display = "none"; + openOuter.innerHTML = ""; + const openButton = document.getElementById("openSideBarButton"); + openButton.style.top = `${rect.top + window.scrollY - 2}px`; + openButton.addEventListener("click", () => { + sidebar.style.display = "flex"; + openOuter.innerHTML = ""; + }); + }); +} + +document.querySelectorAll(".qualityButtons").forEach((btn) => { + btn.addEventListener("click", () => { + quality = btn.id; + if (currentPointCloud) { + const files = getPointCloudFiles(); + loadPointCloud(files[document.getElementById("pointcloud").value]); + } + document.querySelectorAll(".qualityButtons").forEach((b) => b.classList.remove("active")); + btn.classList.add("active"); + }); +}); + +document.querySelectorAll(".colorButtons").forEach((btn) => { + btn.addEventListener("click", () => { + document.querySelectorAll(".colorButtons").forEach((b) => b.classList.remove("active")); + btn.classList.add("active"); + }); }); \ No newline at end of file