Commit bade19c9 authored by Pithon Kabiro's avatar Pithon Kabiro
Browse files

Merge branch 'wip_highlight-selected-buildings' into 'master'

Link drop-down list and 3d visualization

The selected building in the drop-down list should now be highlighted 
in the Cesium 3d globe

See merge request !26
parents fe44753a fc9e6f80
Pipeline #5247 passed with stage
in 24 seconds
...@@ -65,6 +65,9 @@ ...@@ -65,6 +65,9 @@
<!-- vanillaSelectBox --> <!-- vanillaSelectBox -->
<link href="./css/thirdparty/vanillaSelectBox.css" rel="stylesheet" /> <link href="./css/thirdparty/vanillaSelectBox.css" rel="stylesheet" />
<!-- SweetAlert -->
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<!-- <!--
Custom JS --> Custom JS -->
<script defer type="module" src="./js/appCesium.js"></script> <script defer type="module" src="./js/appCesium.js"></script>
......
...@@ -19,24 +19,44 @@ const viewer = new Cesium.Viewer("cesiumGlobeContainer", { ...@@ -19,24 +19,44 @@ const viewer = new Cesium.Viewer("cesiumGlobeContainer", {
}); });
/** /**
* Load and zoom to the extents of 3DTiles * Add a tileset containing buildings
*
* @param {String} urlTiles URL of the 3DTiles to be loaded * @param {String} urlTiles URL of the 3DTiles to be loaded
* @returns {undefined} undefined * @returns {Object} The tileset dataset
*/ */
const loadTiles = function (urlTiles) { const createBuildingTileset = function (urlTiles) {
const tileset = new Cesium.Cesium3DTileset({ return new Cesium.Cesium3DTileset({
url: urlTiles, url: urlTiles,
}); });
viewer.scene.primitives.add(tileset); };
// 3D tileset with all buildings
const nonDetailedBuilding225Tileset = createBuildingTileset(
"data_3d/3dtiles/1_full/tileset.json"
);
// 3D tileset with all buildings except Bau 225
const detailedBuilding225Tileset = createBuildingTileset(
"data_3d/3dtiles/2_partial/tileset.json"
);
tileset.readyPromise.then(function () { /**
* Load and zoom to the extents of 3DTiles
* @param {Object} buildingTileset The 3D tileset to be loaded
* @returns {undefined} undefined
*/
const loadTiles = function (buildingTileset) {
// Add the tileset to the viewer
viewer.scene.primitives.add(buildingTileset);
buildingTileset.readyPromise.then(function () {
viewer viewer
.zoomTo( .zoomTo(
tileset, buildingTileset,
new Cesium.HeadingPitchRange( new Cesium.HeadingPitchRange(
0.0, 0.0,
-0.5, -0.5,
tileset.boundingSphere.radius / 0.5 buildingTileset.boundingSphere.radius / 0.5
) )
) )
.otherwise(function (err) { .otherwise(function (err) {
...@@ -59,11 +79,8 @@ const loadTiles = function (urlTiles) { ...@@ -59,11 +79,8 @@ const loadTiles = function (urlTiles) {
* @returns {undefined} undefined * @returns {undefined} undefined
*/ */
const loadNonDetailedBuilding225 = function () { const loadNonDetailedBuilding225 = function () {
// Paths to data sources // 3D tileset with all buildings
const URL_3DTILES = "data_3d/3dtiles/1_full/tileset.json"; loadTiles(nonDetailedBuilding225Tileset);
// Tileset with all buildings
loadTiles(URL_3DTILES);
}; };
/** /**
...@@ -93,12 +110,11 @@ const gltfLoad = function (gltfUrl, gltfId) { ...@@ -93,12 +110,11 @@ const gltfLoad = function (gltfUrl, gltfId) {
* @returns {undefined} undefined * @returns {undefined} undefined
*/ */
const loadDetailedBuilding225 = function () { const loadDetailedBuilding225 = function () {
// Paths to data sources // Path to glTF data source
const URL_3DTILES = "data_3d/3dtiles/2_partial/tileset.json";
const URL_GLTF = "data_3d/gltf"; const URL_GLTF = "data_3d/gltf";
// Tileset without building 225 // Tileset without building 225
loadTiles(URL_3DTILES); loadTiles(detailedBuilding225Tileset);
// Load Building 225 // Load Building 225
gltfLoad(URL_GLTF, "bosch_si225_3"); gltfLoad(URL_GLTF, "bosch_si225_3");
...@@ -286,3 +302,74 @@ const activate3DTileFeaturePicking = function () { ...@@ -286,3 +302,74 @@ const activate3DTileFeaturePicking = function () {
}; };
activate3DTileFeaturePicking(); activate3DTileFeaturePicking();
/**
* Reset the styling for all buildings contained in a 3D tileset. The default colour is `white`
*
* @param {Object} targetTileset The 3D tileset to be styled
* @returns {undefined} undefined
*/
const resetStylingForAllBuildings = function (targetTileset) {
targetTileset.style = new Cesium.Cesium3DTileStyle({
color: {
conditions: [["true", 'color("white")']],
},
});
};
/**
* Apply a different color to the buildings that are selected in the buildings & data points drop-down list
*
* @param {Object} targetTileset The 3D tileset to be styled
* @param {Array} buildingIdArr An array of building IDs
* @returns {undefined} undefined
*/
const applyStylingForSelectedBuildings = function (
targetTileset,
buildingIdArr
) {
targetTileset.style = new Cesium.Cesium3DTileStyle({
color: {
conditions: [
// The maximum number of buildings = seven
["${_gebaeude} === " + buildingIdArr[0], 'color("red")'],
["${_gebaeude} === " + buildingIdArr[1], 'color("red")'],
["${_gebaeude} === " + buildingIdArr[2], 'color("red")'],
["${_gebaeude} === " + buildingIdArr[3], 'color("red")'],
["${_gebaeude} === " + buildingIdArr[4], 'color("red")'],
["${_gebaeude} === " + buildingIdArr[5], 'color("red")'],
["${_gebaeude} === " + buildingIdArr[6], 'color("red")'],
["true", 'color("white")'],
],
},
});
};
/**
* Highlight the building(s) that are selected in the buildings & data points drop-down list
*
* @param {Array} selectedBldgsDataPntsSmplngRateAbbrevNestedArr An array which contains one or more nested arrays of abbreviations of building(s), data point(s) and sampling rate(s)
* @returns {undefined} undefined
*/
const highlightSelectedBuildings = function (
selectedBldgsDataPntsSmplngRateAbbrevNestedArr
) {
// The building ID is the first element
const buildingIdArr = selectedBldgsDataPntsSmplngRateAbbrevNestedArr.map(
(bldgDataPtSmplngRateAbbrev) => bldgDataPtSmplngRateAbbrev[0]
);
// Use a set to remove duplicates
const uniqueBuildingIdArr = [...new Set(buildingIdArr)];
applyStylingForSelectedBuildings(
nonDetailedBuilding225Tileset,
uniqueBuildingIdArr
);
};
export {
nonDetailedBuilding225Tileset,
resetStylingForAllBuildings,
highlightSelectedBuildings,
};
...@@ -40,6 +40,7 @@ import { ...@@ -40,6 +40,7 @@ import {
checkIfSelectedBuildingDataPointsOptionsAreValid, checkIfSelectedBuildingDataPointsOptionsAreValid,
checkIfSelectedAggregationOptionsAreValid, checkIfSelectedAggregationOptionsAreValid,
getAbbreviationsForSelectedOptionsFromAllDropDownLists, getAbbreviationsForSelectedOptionsFromAllDropDownLists,
createErrorPopupMessage,
} from "./src_modules/dropDownListHelpers.mjs"; } from "./src_modules/dropDownListHelpers.mjs";
import { drawColumnChartBasedOnSelectedOptions } from "./src_modules/dropDownListChartColumn.mjs"; import { drawColumnChartBasedOnSelectedOptions } from "./src_modules/dropDownListChartColumn.mjs";
...@@ -50,6 +51,12 @@ import { drawLineChartBasedOnSelectedOptions } from "./src_modules/dropDownListC ...@@ -50,6 +51,12 @@ import { drawLineChartBasedOnSelectedOptions } from "./src_modules/dropDownListC
import { drawScatterPlotBasedOnSelectedOptions } from "./src_modules/dropDownListChartScatterPlot.mjs"; import { drawScatterPlotBasedOnSelectedOptions } from "./src_modules/dropDownListChartScatterPlot.mjs";
import {
nonDetailedBuilding225Tileset,
resetStylingForAllBuildings,
highlightSelectedBuildings,
} from "./appCesium.js";
/** /**
* Callback function that wraps the logic of populating the linked drop down lists. * Callback function that wraps the logic of populating the linked drop down lists.
* Will run on `DOMContentLoaded` event * Will run on `DOMContentLoaded` event
...@@ -70,6 +77,9 @@ const afterDocumentLoads = function () { ...@@ -70,6 +77,9 @@ const afterDocumentLoads = function () {
*/ */
const drawChartUsingSelectedOptions = async function () { const drawChartUsingSelectedOptions = async function () {
try { try {
// Reset the styling of the 3D tileset, in case building(s) were highlighted
resetStylingForAllBuildings(nonDetailedBuilding225Tileset);
// Note: The chart type amd aggregation type + duration are the first and // Note: The chart type amd aggregation type + duration are the first and
// third elements respectively, we have ignored the second and fourth elements // third elements respectively, we have ignored the second and fourth elements
const [selectedChartTypeArr, , selectedAggregationTypeDurationArr] = const [selectedChartTypeArr, , selectedAggregationTypeDurationArr] =
...@@ -94,6 +104,11 @@ const drawChartUsingSelectedOptions = async function () { ...@@ -94,6 +104,11 @@ const drawChartUsingSelectedOptions = async function () {
const [[, , selectedSamplingRateAbbrev]] = const [[, , selectedSamplingRateAbbrev]] =
selectedBuildingsDataPointsSamplingRateAbbrevNestedArr; selectedBuildingsDataPointsSamplingRateAbbrevNestedArr;
// Highlight the selected buildings
highlightSelectedBuildings(
selectedBuildingsDataPointsSamplingRateAbbrevNestedArr
);
// User-specified start date and end date for aggregation - used by MULTIPLE chart types // User-specified start date and end date for aggregation - used by MULTIPLE chart types
const AGGREGATION_START_DATE = "2020-01-01"; const AGGREGATION_START_DATE = "2020-01-01";
const AGGREGATION_STOP_DATE = "2020-12-31"; const AGGREGATION_STOP_DATE = "2020-12-31";
...@@ -256,8 +271,8 @@ const drawChartUsingSelectedOptions = async function () { ...@@ -256,8 +271,8 @@ const drawChartUsingSelectedOptions = async function () {
} catch (err) { } catch (err) {
console.error(err); console.error(err);
// Display a dialog window with the error message // Display a popup that displays the error message
alert(err); createErrorPopupMessage(err);
} finally { } finally {
// Enable the 'draw chart' button // Enable the 'draw chart' button
enableDrawChartButton(); enableDrawChartButton();
......
...@@ -471,6 +471,20 @@ const getAbbreviationsForSelectedOptionsFromAllDropDownLists = function ( ...@@ -471,6 +471,20 @@ const getAbbreviationsForSelectedOptionsFromAllDropDownLists = function (
} }
}; };
/**
* Create a pop up message (when an error is thrown) using the SweetAlert library
*
* @param {Object} errorObj An error object
* @returns {undefined} undefined
*/
const createErrorPopupMessage = function (errorObj) {
swal({
title: "Something went wrong!",
text: `${errorObj.message}`,
icon: "error",
});
};
export { export {
splitMultipleOptionsTextDelimitedBySlash, splitMultipleOptionsTextDelimitedBySlash,
getSelectedOptionsFromAllDropDownLists, getSelectedOptionsFromAllDropDownLists,
...@@ -481,4 +495,5 @@ export { ...@@ -481,4 +495,5 @@ export {
checkIfSelectedBuildingDataPointsOptionsAreValid, checkIfSelectedBuildingDataPointsOptionsAreValid,
checkIfSelectedAggregationOptionsAreValid, checkIfSelectedAggregationOptionsAreValid,
getAbbreviationsForSelectedOptionsFromAllDropDownLists, getAbbreviationsForSelectedOptionsFromAllDropDownLists,
createErrorPopupMessage,
}; };
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment