diff --git a/public/js/appCesium.js b/public/js/appCesium.js index 6df780922c57583f3f6c36d3ac25d7fdd2ae86af..ce1fcb3b6482851b6dc8a0d2f2762406762a324d 100644 --- a/public/js/appCesium.js +++ b/public/js/appCesium.js @@ -120,3 +120,139 @@ if (!LOAD_DETAILED_BLDG225) { // Alternative case: load 3dTiles + glTF loadDetailed(); } + +/** + * Activate feature picking for the displayed 3DTiles + * @param {*} + * @returns {void} + */ +const activate3DTileFeaturePicking = function () { + // HTML overlay for showing feature name on mouseover + const nameOverlay = document.createElement("div"); + viewer.container.appendChild(nameOverlay); + nameOverlay.className = "backdrop"; + nameOverlay.style.display = "none"; + nameOverlay.style.position = "absolute"; + nameOverlay.style.bottom = "0"; + nameOverlay.style.left = "0"; + nameOverlay.style["pointer-events"] = "none"; + nameOverlay.style.padding = "4px"; + nameOverlay.style.backgroundColor = "black"; + nameOverlay.style.color = "white"; + nameOverlay.style.fontFamily = "Fira Sans, sans-serif"; + nameOverlay.style.fontSize = "0.75em"; + + // Information about the currently selected feature + const selected = { + feature: undefined, + originalColor: new Cesium.Color(), + }; + + // An entity object which will hold info about the currently selected feature for infobox display + const selectedEntity = new Cesium.Entity(); + + // Get default left click handler for when a feature is not picked on left click + const clickHandler = viewer.screenSpaceEventHandler.getInputAction( + Cesium.ScreenSpaceEventType.LEFT_CLICK + ); + + // Change the feature color on mouse over + + // Information about the currently highlighted feature + const highlighted = { + feature: undefined, + originalColor: new Cesium.Color(), + }; + + // Color a feature on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove(movement) { + // If a feature was previously highlighted, undo the highlight + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + nameOverlay.style.display = "none"; + return; + } + // A feature was picked, so show it's overlay content + nameOverlay.style.display = "block"; + nameOverlay.style.bottom = + viewer.canvas.clientHeight - movement.endPosition.y + "px"; + nameOverlay.style.left = movement.endPosition.x + "px"; + let name = pickedFeature.getProperty("name"); + if (!Cesium.defined(name)) { + name = pickedFeature.getProperty("id"); + } + nameOverlay.textContent = name; + // Highlight the feature if it's not already selected. + if (pickedFeature !== selected.feature) { + highlighted.feature = pickedFeature; + Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); + pickedFeature.color = Cesium.Color.GREY; + } + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + + // Color a feature on selection and show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(movement) { + // If a feature was previously selected, undo the highlight + if (Cesium.defined(selected.feature)) { + selected.feature.color = selected.originalColor; + selected.feature = undefined; + } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + clickHandler(movement); + return; + } + // Select the feature if it's not already selected + if (selected.feature === pickedFeature) { + return; + } + selected.feature = pickedFeature; + // Save the selected feature's original color + if (pickedFeature === highlighted.feature) { + Cesium.Color.clone(highlighted.originalColor, selected.originalColor); + highlighted.feature = undefined; + } else { + Cesium.Color.clone(pickedFeature.color, selected.originalColor); + } + // Highlight newly selected feature + pickedFeature.color = Cesium.Color.LIME; + // Set feature infobox description + const featureName = pickedFeature.getProperty("name"); + selectedEntity.name = featureName; + selectedEntity.description = + 'Loading <div class="cesium-infoBox-loading"></div>'; + viewer.selectedEntity = selectedEntity; + selectedEntity.description = ` + <table class="cesium-infoBox-defaultTable"> + <tbody> + <tr><th>Bau</th><td> + ${pickedFeature.getProperty("BIN")} + </td></tr> + <tr><th>Nutzung</th><td> + ${pickedFeature.getProperty("DOITT_ID")} + </td></tr> + <tr><th>Baujahr</th><td> + ${pickedFeature.getProperty("SOURCE_ID")} + </td></tr> + <tr><th>Geschosse</th><td> + ${pickedFeature.getProperty("longitude")} + </td></tr> + <tr><th>Gebäudefläche</th><td> + ${pickedFeature.getProperty("latitude")} + </td></tr> + <tr><th>Gebäudevolumen</th><td> + ${pickedFeature.getProperty("height")} + </td></tr> + </tbody> + </table> + `; + }, Cesium.ScreenSpaceEventType.LEFT_CLICK); +}; + +activate3DTileFeaturePicking();