123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- import Color from "../Core/Color.js";
- import defined from "../Core/defined.js";
- import JulianDate from "../Core/JulianDate.js";
- import CesiumMath from "../Core/Math.js";
- /**
- * A heatmap colorizer in a {@link Cesium3DTileset}. A tileset can colorize its visible tiles in a heatmap style.
- *
- * @alias Cesium3DTilesetHeatmap
- * @constructor
- * @private
- */
- function Cesium3DTilesetHeatmap(tilePropertyName) {
- /**
- * The tile variable to track for heatmap colorization.
- * Tile's will be colorized relative to the other visible tile's values for this variable.
- *
- * @type {string}
- */
- this.tilePropertyName = tilePropertyName;
- // Members that are updated every time a tile is colorized
- this._minimum = Number.MAX_VALUE;
- this._maximum = -Number.MAX_VALUE;
- // Members that are updated once every frame
- this._previousMinimum = Number.MAX_VALUE;
- this._previousMaximum = -Number.MAX_VALUE;
- // If defined uses a reference minimum maximum to colorize by instead of using last frames minimum maximum of rendered tiles.
- // For example, the _loadTimestamp can get a better colorization using setReferenceMinimumMaximum in order to take accurate colored timing diffs of various scenes.
- this._referenceMinimum = {};
- this._referenceMaximum = {};
- }
- /**
- * Convert to a usable heatmap value (i.e. a number). Ensures that tile values that aren't stored as numbers can be used for colorization.
- * @private
- */
- function getHeatmapValue(tileValue, tilePropertyName) {
- let value;
- if (tilePropertyName === "_loadTimestamp") {
- value = JulianDate.toDate(tileValue).getTime();
- } else {
- value = tileValue;
- }
- return value;
- }
- /**
- * Sets the reference minimum and maximum for the variable name. Converted to numbers before they are stored.
- *
- * @param {object} minimum The minimum reference value.
- * @param {object} maximum The maximum reference value.
- * @param {string} tilePropertyName The tile variable that will use these reference values when it is colorized.
- */
- Cesium3DTilesetHeatmap.prototype.setReferenceMinimumMaximum = function (
- minimum,
- maximum,
- tilePropertyName
- ) {
- this._referenceMinimum[tilePropertyName] = getHeatmapValue(
- minimum,
- tilePropertyName
- );
- this._referenceMaximum[tilePropertyName] = getHeatmapValue(
- maximum,
- tilePropertyName
- );
- };
- function getHeatmapValueAndUpdateMinimumMaximum(heatmap, tile) {
- const tilePropertyName = heatmap.tilePropertyName;
- if (defined(tilePropertyName)) {
- const heatmapValue = getHeatmapValue(
- tile[tilePropertyName],
- tilePropertyName
- );
- if (!defined(heatmapValue)) {
- heatmap.tilePropertyName = undefined;
- return heatmapValue;
- }
- heatmap._maximum = Math.max(heatmapValue, heatmap._maximum);
- heatmap._minimum = Math.min(heatmapValue, heatmap._minimum);
- return heatmapValue;
- }
- }
- const heatmapColors = [
- new Color(0.1, 0.1, 0.1, 1), // Dark Gray
- new Color(0.153, 0.278, 0.878, 1), // Blue
- new Color(0.827, 0.231, 0.49, 1), // Pink
- new Color(0.827, 0.188, 0.22, 1), // Red
- new Color(1.0, 0.592, 0.259, 1), // Orange
- new Color(1.0, 0.843, 0.0, 1),
- ]; // Yellow
- /**
- * Colorize the tile in heat map style based on where it lies within the minimum maximum window.
- * Heatmap colors are black, blue, pink, red, orange, yellow. 'Cold' or low numbers will be black and blue, 'Hot' or high numbers will be orange and yellow,
- * @param {Cesium3DTile} tile The tile to colorize relative to last frame's minimum and maximum values of all visible tiles.
- * @param {FrameState} frameState The frame state.
- */
- Cesium3DTilesetHeatmap.prototype.colorize = function (tile, frameState) {
- const tilePropertyName = this.tilePropertyName;
- if (
- !defined(tilePropertyName) ||
- !tile.contentAvailable ||
- tile._selectedFrame !== frameState.frameNumber
- ) {
- return;
- }
- const heatmapValue = getHeatmapValueAndUpdateMinimumMaximum(this, tile);
- const minimum = this._previousMinimum;
- const maximum = this._previousMaximum;
- if (minimum === Number.MAX_VALUE || maximum === -Number.MAX_VALUE) {
- return;
- }
- // Shift the minimum maximum window down to 0
- const shiftedMax = maximum - minimum + CesiumMath.EPSILON7; // Prevent divide by 0
- const shiftedValue = CesiumMath.clamp(
- heatmapValue - minimum,
- 0.0,
- shiftedMax
- );
- // Get position between minimum and maximum and convert that to a position in the color array
- const zeroToOne = shiftedValue / shiftedMax;
- const lastIndex = heatmapColors.length - 1.0;
- const colorPosition = zeroToOne * lastIndex;
- // Take floor and ceil of the value to get the two colors to lerp between, lerp using the fractional portion
- const colorPositionFloor = Math.floor(colorPosition);
- const colorPositionCeil = Math.ceil(colorPosition);
- const t = colorPosition - colorPositionFloor;
- const colorZero = heatmapColors[colorPositionFloor];
- const colorOne = heatmapColors[colorPositionCeil];
- // Perform the lerp
- const finalColor = Color.clone(Color.WHITE);
- finalColor.red = CesiumMath.lerp(colorZero.red, colorOne.red, t);
- finalColor.green = CesiumMath.lerp(colorZero.green, colorOne.green, t);
- finalColor.blue = CesiumMath.lerp(colorZero.blue, colorOne.blue, t);
- tile._debugColor = finalColor;
- };
- /**
- * Resets the tracked minimum maximum values for heatmap colorization. Happens right before tileset traversal.
- */
- Cesium3DTilesetHeatmap.prototype.resetMinimumMaximum = function () {
- // For heat map colorization
- const tilePropertyName = this.tilePropertyName;
- if (defined(tilePropertyName)) {
- const referenceMinimum = this._referenceMinimum[tilePropertyName];
- const referenceMaximum = this._referenceMaximum[tilePropertyName];
- const useReference = defined(referenceMinimum) && defined(referenceMaximum);
- this._previousMinimum = useReference ? referenceMinimum : this._minimum;
- this._previousMaximum = useReference ? referenceMaximum : this._maximum;
- this._minimum = Number.MAX_VALUE;
- this._maximum = -Number.MAX_VALUE;
- }
- };
- export default Cesium3DTilesetHeatmap;
|