"use strict"; Cesium.Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIyODgxYzJlNi1kNDZiLTQ3ZmQtYmUxYy0yMWI0OGM3NDA5MzAiLCJpZCI6NDczOSwic2NvcGVzIjpbImFzciIsImdjIl0sImlhdCI6MTU0MTUyMzU0MX0.shj2hM3pvsvcmE_wMb2aBDuk_cKWmFmbolltInGImwU"; // Flag to determine models that will be loaded // Set to `true` or `false` // `true` - load a detailed model of Building 225 // `false` - load a non-detailed model of Building 225 const LOAD_DETAILED_BLDG225 = false; // Global variable const viewer = new Cesium.Viewer("cesiumGlobeContainer", { scene3DOnly: true, imageryProvider: Cesium.createOpenStreetMapImageryProvider({ url: "https://a.tile.openstreetmap.org/", }), }); /** * Load and zoom to the extents of 3DTiles * @param {String} urlTiles URL of the 3DTiles to be loaded * @returns {undefined} undefined */ const loadTiles = function (urlTiles) { const tileset = new Cesium.Cesium3DTileset({ url: urlTiles, }); viewer.scene.primitives.add(tileset); tileset.readyPromise.then(function () { viewer .zoomTo( tileset, new Cesium.HeadingPitchRange( 0.0, -0.5, tileset.boundingSphere.radius / 0.5 ) ) .otherwise(function (err) { throw err; }); }); // Override the default home homeButton; doesn't work perfectly viewer.homeButton.viewModel.command.beforeExecute.addEventListener(function ( e ) { e.cancel = true; viewer.scene.camera.flyToBoundingSphere(tileset.boundingSphere); }); }; /** * Load 3DTiles for all the buildings; ignore any glTF models * @param{*} * @returns {undefined} undefined */ const loadNonDetailedBuilding225 = function () { // Paths to data sources const URL_3DTILES = "data_3d/3dtiles/1_full/tileset.json"; // Tileset with all buildings loadTiles(URL_3DTILES); }; /** * Load glTF models * @param {String} gltfUrl Path to the folder containing the glTF models * @param {String} gltfId Name of the glTF model file without the extension i.e. exclude the `.gltf` suffix * @returns {undefined} undefined */ const gltfLoad = function (gltfUrl, gltfId) { const modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame( Cesium.Cartesian3.fromDegrees(9.083385, 48.881342, 0) ); viewer.scene.primitives.add( Cesium.Model.fromGltf({ url: `${gltfUrl}/${gltfId}.gltf`, modelMatrix: modelMatrix, scale: 0.0254, allowPicking: true, }) ); }; /** * Load detailed glTF models for Building 225 and 3DTiles for the rest of the buildings * @param{*} * @returns {undefined} undefined */ const loadDetailedBuilding225 = function () { // Paths to data sources const URL_3DTILES = "data_3d/3dtiles/2_partial/tileset.json"; const URL_GLTF = "data_3d/gltf"; // Tileset without building 225 loadTiles(URL_3DTILES); // Load Building 225 gltfLoad(URL_GLTF, "bosch_si225_3"); // Load sensors in Building 225 const gltfArray = [ "sensor_013", "sensor_023", "sensor_033", "sensor_053", "sensor_063", "sensor_073", "sensor_083", "sensor_093", "sensor_103", "sensor_113", "sensor_123", "sensor_133", "sensor_143", "sensor_153", "sensor_163", "sensor_173", "sensor_183", "sensor_213", "sensor_223", "sensor_233", "sensor_253", "sensor_263", "sensor_273", "sensor_283", "sensor_293", "sensor_303", "sensor_313", "sensor_323", "sensor_333", "sensor_343", "sensor_353", "sensor_363", "sensor_373", "sensor_383_v2", ]; gltfArray.forEach((sensor) => gltfLoad(URL_GLTF, sensor)); }; // Default case: load only 3dTiles // Alternative case: load 3dTiles + glTF if (LOAD_DETAILED_BLDG225) { loadDetailedBuilding225(); } else { loadNonDetailedBuilding225(); } /** * Activate feature picking for the displayed 3DTiles * @param {*} * @returns {undefined} undefined */ 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("_gebaeude"); 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
'; viewer.selectedEntity = selectedEntity; selectedEntity.description = `
Bau ${pickedFeature.getProperty("_gebaeude")}
Nutzung ${pickedFeature.getProperty("_nutzung")}
Baujahr ${pickedFeature.getProperty("_baujahr")}
Geschosse ${pickedFeature.getProperty("_geschosse")}
Gebäudefläche (m2) ${pickedFeature.getProperty("_gebaeudeflaeche")}
`; const clickedBuilding = pickedFeature.getProperty("_gebaeude"); }, Cesium.ScreenSpaceEventType.LEFT_CLICK); }; activate3DTileFeaturePicking();