| 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;
 |