text: import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
  
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
  
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
  
  import { getBounds, boundsContain, packVertices, scaleToAspectRatio, getTextureCoordinates, getTextureParams } from './heatmap-layer-utils';
  import { Buffer, Texture2D, Transform, getParameter, FEATURES, hasFeatures, isWebGL2 } from '@luma.gl/core';
  import { CompositeLayer, AttributeManager, COORDINATE_SYSTEM, log } from '@deck.gl/core';
  import TriangleLayer from './triangle-layer';
  import { defaultColorRange, colorRangeToFlatArray } from '../utils/color-utils';
  import weights_vs from './weights-vs.glsl';
  import weights_fs from './weights-fs.glsl';
  import vs_max from './max-vs.glsl';
  const RESOLUTION = 2;
  const SIZE_2K = 2048;
  const ZOOM_DEBOUNCE = 500;
  const TEXTURE_OPTIONS = {
    mipmaps: false,
    parameters: {
      [10240]: 9729,
      [10241]: 9729,
      [10242]: 33071,
      [10243]: 33071
    },
    dataFormat: 6408
  };
  const DEFAULT_COLOR_DOMAIN = [0, 0];
  const defaultProps = {
    getPosition: {
      type: 'accessor',
      value: x => x.position
    },
    getWeight: {
      type: 'accessor',
      value: 1
    },
    intensity: {
      type: 'number',
      min: 0,
      value: 1
    },
    radiusPixels: {
      type: 'number',
      min: 1,
      max: 100,
      value: 30
    },
    colorRange: defaultColorRange,
    threshold: {
      type: 'number',
      min: 0,
      max: 1,
      value: 0.05
    },
    colorDomain: {
      type: 'array',
      value: null,
      optional: true
    }
  };
  const REQUIRED_FEATURES = [FEATURES.BLEND_EQUATION_MINMAX, FEATURES.TEXTURE_FLOAT];
  export default class HeatmapLayer extends CompositeLayer {
    initializeState() {
      const {
        gl
      } = this.context;
  
      if (!hasFeatures(gl, REQUIRED_FEATURES)) {
        this.setState({
          supported: false
        });
        log.error("HeatmapLayer: ".concat(this.id, " is not supported on this browser"))();
        return;
      }
  
      this.setState({
        supported: true
      });
  
      this._setupTextureParams();
  
      this._setupAttributes();
  
      this._setupResources();
    }
  
    shouldUpdateState({
      changeFlags
    }) {
      return changeFlags.somethingChanged;
    }
  
    updateState(opts) {
      if (!this.state.supported) {
        return;
      }
  
      super.updateState(opts);
      const {
        props,
        oldProps
      } = opts;
  
      const changeFlags = this._getChangeFlags(opts);
  
      if (changeFlags.viewportChanged) {
        changeFlags.boundsChanged = this._updateBounds();
      }
  
      if (changeFlags.dataChanged || changeFlags.boundsChanged || changeFlags.uniformsChanged) {
        this._updateWeightmap();
      } else if (changeFlags.viewportZoomChanged) {
        this._debouncedUpdateWeightmap();
      }
  
      if (props.colorRange !== oldProps.colorRange) {
        this._updateColorTexture(opts);
      }
  
      if (changeFlags.viewportChanged) {
        this._updateTextureRenderingBounds();
      }
  
      if (oldProps.colorDomain !== props.colorDomain || changeFlags.viewportChanged) {
        const {
          viewport
        } = this.context;
        const {
          weightsScale
        } = this.state;
        const domainScale = (viewport ? 1024 / viewport.scale : 1) * weightsScale;
        const colorDomain = props.colorDomain ? props.colorDomain.map(x => x * domainScale) : DEFAULT_COLOR_DOMAIN;
  
        if (colorDomain[1] > 0 && weightsScale < 1) {
          const max = Math.min(colorDomain[1], 1);
          colorDomain[0] *= max / colorDomain[1];
          colorDomain[1] = max;
        }
  
        this.setState({
          colorDomain
        });
      }
  
      this.setState({
        zoom: opts.context.viewport.zoom
      });
    }
  
    renderLayers() {
      if (!this.state.supported) {
        return [];
      }
  
      const {
        weightsTexture,
        triPositionBuffer,
        triTexCoordBuffer,
        maxWeightsTexture,
        colorTexture,
        colorDomain
      } = this.state;
      const {
        updateTriggers,
        intensity,
        threshold
      } = this.props;
      return new TriangleLayer(this.getSubLayerProps({
        id: 'triangle-layer',
        updateTriggers
      }), {
        data: {
          attributes: {
            positions: triPositionBuffer,
            texCoords: triTexCoordBuffer
          }
        },
        vertexCount: 4,
        maxTexture: maxWeightsTexture,
        colorTexture,
        texture: weightsTexture,
        intensity,
        threshold,
        colorDomain
      });
    }
  
    finalizeState() {
      super.finalizeState();
      const {
        weightsTransform,
        weightsTexture,
        maxWeightTransform,
        maxWeightsTexture,
        triPositionBuffer,
        triTexCoordBuffer,
        colorTexture
      } = this.state;
      weightsTransform && weightsTransform.delete();
      weightsTexture && weightsTexture.delete();
      maxWeightTransform && maxWeightTransform.delete();
      maxWeightsTexture && maxWeightsTexture.delete();
      triPositionBuffer && triPositionBuffer.delete();
      triTexCoordBuffer && triTexCoordBuffer.delete();
      colorTexture && colorTexture.delete();
    }
  
    _getAttributeManager() {
      return new AttributeManager(this.context.gl, {
        id: this.props.id,
        stats: this.context.stats
      });
    }
  
    _getChangeFlags(opts) {
      const {
        oldProps,
        props
      } = opts;
      const changeFlags = {};
  
      if (this._isDataChanged(opts)) {
        changeFlags.dataChanged = true;
      }
  
      if (oldProps.radiusPixels !== props.radiusPixels) {
        changeFlags.uniformsChanged = true;
      }
  
      changeFlags.viewportChanged = opts.changeFlags.viewportChanged;
      const {
        zoom
      } = this.state;
  
      if (!opts.context.viewport || opts.context.viewport.zoom !== zoom) {
        changeFlags.viewportZoomChanged = true;
      }
  
      return changeFlags;
    }
  
    _getTextures() {
      const {
        gl
      } = this.context;
      const {
        textureSize,
        format,
        type
      } = this.state;
      return {
        weightsTexture: new Texture2D(gl, _objectSpread({
          width: textureSize,
          height: textureSize,
          format,
          type
        }, TEXTURE_OPTIONS)),
        maxWeightsTexture: new Texture2D(gl, _objectSpread({
          format,
          type
        }, TEXTURE_OPTIONS))
      };
    }
  
    _isDataChanged({
      changeFlags
    }) {
      if (changeFlags.dataChanged) {
        return true;
      }
  
      if (changeFlags.updateTriggersChanged && (changeFlags.updateTriggersChanged.all || changeFlags.updateTriggersChanged.getPosition || changeFlags.updateTriggersChanged.getWeight)) {
        return true;
      }
  
      return false;
    }
  
    _setupAttributes() {
      const attributeManager = this.getAttributeManager();
      attributeManager.add({
        positions: {
          size: 3,
          accessor: 'getPosition'
        },
        weights: {
          size: 1,
          accessor: 'getWeight'
        }
      });
    }
  
    _setupTextureParams() {
      const {
        gl
      } = this.context;
      const textureSize = Math.min(SIZE_2K, getParameter(gl, 3379));
      const floatTargetSupport = hasFeatures(gl, FEATURES.COLOR_ATTACHMENT_RGBA32F);
      const {
        format,
        type
      } = getTextureParams({
        gl,
        floatTargetSupport
      });
      const weightsScale = floatTargetSupport ? 1 : 1 / 255;
      this.setState({
        textureSize,
        format,
        type,
        weightsScale
      });
  
      if (!floatTargetSupport) {
        log.warn("HeatmapLayer: ".concat(this.id, " rendering to float texture not supported, fallingback to low precession format"))();
      }
    }
  
    _setupResources() {
      const {
        gl
      } = this.context;
      const {
        textureSize
      } = this.state;
  
      const {
        weightsTexture,
        maxWeightsTexture
      } = this._getTextures();
  
      const weightsTransform = new Transform(gl, {
        id: "".concat(this.id, "-weights-transform"),
        vs: weights_vs,
        _fs: weights_fs,
        modules: ['project32'],
        elementCount: 1,
        _targetTexture: weightsTexture,
        _targetTextureVarying: 'weightsTexture'
      });
      const maxWeightTransform = new Transform(gl, {
        id: "".concat(this.id, "-max-weights-transform"),
        _sourceTextures: {
          inTexture: weightsTexture
        },
        _targetTexture: maxWeightsTexture,
        _targetTextureVarying: 'outTexture',
        vs: vs_max,
        elementCount: textureSize * textureSize
      });
      this.setState({
        weightsTexture,
        maxWeightsTexture,
        weightsTransform,
        model: weightsTransform.model,
        maxWeightTransform,
        zoom: null,
        triPositionBuffer: new Buffer(gl, {
          byteLength: 48,
          accessor: {
            size: 3
          }
        }),
        triTexCoordBuffer: new Buffer(gl, {
          byteLength: 48,
          accessor: {
            size: 2
          }
        })
      });
    }
  
    _updateMaxWeightValue() {
      const {
        maxWeightTransform
      } = this.state;
      maxWeightTransform.run({
        parameters: {
          blend: true,
          depthTest: false,
          blendFunc: [1, 1],
          blendEquation: 32776
        }
      });
    }
  
    _updateBounds(forceUpdate = false) {
      const {
        textureSize
      } = this.state;
      const {
        viewport
      } = this.context;
      const viewportCorners = [viewport.unproject([0, 0]), viewport.unproject([viewport.width, 0]), viewport.unproject([viewport.width, viewport.height]), viewport.unproject([0, viewport.height])];
      const visibleWorldBounds = getBounds(viewportCorners);
  
      const visibleCommonBounds = this._worldToCommonBounds(visibleWorldBounds);
  
      const newState = {
        visibleWorldBounds,
        viewportCorners
      };
      let boundsChanged = false;
  
      if (forceUpdate || !this.state.worldBounds || !boundsContain(this.state.worldBounds, visibleWorldBounds)) {
        const scaledCommonBounds = scaleToAspectRatio(visibleCommonBounds, textureSize * RESOLUTION, textureSize * RESOLUTION);
  
        const worldBounds = this._commonToWorldBounds(scaledCommonBounds);
  
        if (this.props.coordinateSystem === COORDINATE_SYSTEM.LNGLAT) {
          worldBounds[1] = Math.max(worldBounds[1], -85.051129);
          worldBounds[3] = Math.min(worldBounds[3], 85.051129);
          worldBounds[0] = Math.max(worldBounds[0], -360);
          worldBounds[2] = Math.min(worldBounds[2], 360);
        }
  
        const normalizedCommonBounds = this._worldToCommonBounds(worldBounds, {
          scaleToAspect: true,
          normalize: true,
          width: textureSize * RESOLUTION,
          height: textureSize * RESOLUTION
        });
  
        newState.worldBounds = worldBounds;
        newState.normalizedCommonBounds = normalizedCommonBounds;
        boundsChanged = true;
      }
  
      this.setState(newState);
      return boundsChanged;
    }
  
    _updateTextureRenderingBounds() {
      const {
        triPositionBuffer,
        triTexCoordBuffer,
        normalizedCommonBounds,
        viewportCorners
      } = this.state;
      const {
        viewport
      } = this.context;
      const commonBounds = normalizedCommonBounds.map(x => x * viewport.scale);
      triPositionBuffer.subData(packVertices(viewportCorners, 3));
      const textureBounds = viewportCorners.map(p => getTextureCoordinates(viewport.projectPosition(p), commonBounds));
      triTexCoordBuffer.subData(packVertices(textureBounds, 2));
    }
  
    _updateColorTexture(opts) {
      const {
        colorRange
      } = opts.props;
      let {
        colorTexture
      } = this.state;
      const colors = colorRangeToFlatArray(colorRange, true);
  
      if (colorTexture) {
        colorTexture.setImageData({
          data: colors,
          width: colorRange.length
        });
      } else {
        colorTexture = new Texture2D(this.context.gl, _objectSpread({
          data: colors,
          width: colorRange.length,
          height: 1,
          format: isWebGL2(this.context.gl) ? 34836 : 6408,
          type: 5126
        }, TEXTURE_OPTIONS));
      }
  
      this.setState({
        colorTexture
      });
    }
  
    _updateWeightmap() {
      const {
        radiusPixels
      } = this.props;
      const {
        weightsTransform,
        worldBounds,
        textureSize,
        weightsTexture,
        weightsScale
      } = this.state;
  
      this._updateAttributes(this.props);
  
      const moduleParameters = Object.assign(Object.create(this.props), {
        viewport: this.context.viewport,
        pickingActive: 0
      });
  
      const commonBounds = this._worldToCommonBounds(worldBounds, {
        useLayerCoordinateSystem: true,
        scaleToAspect: true,
        width: textureSize * RESOLUTION,
        height: textureSize * RESOLUTION
      });
  
      const uniforms = Object.assign({}, weightsTransform.model.getModuleUniforms(moduleParameters), {
        radiusPixels,
        commonBounds,
        textureWidth: textureSize,
        weightsScale
      });
      weightsTransform.update({
        elementCount: this.getNumInstances()
      });
      weightsTransform.run({
        uniforms,
        parameters: {
          blend: true,
          depthTest: false,
          blendFunc: [1, 1],
          blendEquation: 32774
        },
        clearRenderTarget: true
      });
  
      this._updateMaxWeightValue();
  
      weightsTexture.setParameters({
        [10240]: 9729,
        [10241]: 9729
      });
      this.setState({
        lastUpdate: Date.now()
      });
    }
  
    _debouncedUpdateWeightmap(fromTimer = false) {
      let {
        updateTimer
      } = this.state;
      const timeSinceLastUpdate = Date.now() - this.state.lastUpdate;
  
      if (fromTimer) {
        updateTimer = null;
      }
  
      if (timeSinceLastUpdate >= ZOOM_DEBOUNCE) {
        this._updateBounds(true);
  
        this._updateWeightmap();
  
        this._updateTextureRenderingBounds();
      } else if (!updateTimer) {
        updateTimer = setTimeout(this._debouncedUpdateWeightmap.bind(this, true), ZOOM_DEBOUNCE - timeSinceLastUpdate);
      }
  
      this.setState({
        updateTimer
      });
    }
  
    _worldToCommonBounds(worldBounds, opts = {}) {
      const {
        useLayerCoordinateSystem = false,
        scaleToAspect = false,
        width,
        height
      } = opts;
      const [minLong, minLat, maxLong, maxLat] = worldBounds;
      const {
        viewport
      } = this.context;
      let topLeftCommon;
      let bottomRightCommon;
  
      if (useLayerCoordinateSystem) {
        topLeftCommon = this.projectPosition([minLong, maxLat, 0]);
        bottomRightCommon = this.projectPosition([maxLong, minLat, 0]);
      } else {
        topLeftCommon = viewport.projectPosition([minLong, maxLat, 0]);
        bottomRightCommon = viewport.projectPosition([maxLong, minLat, 0]);
      }
  
      let commonBounds = topLeftCommon.slice(0, 2).concat(bottomRightCommon.slice(0, 2));
  
      if (scaleToAspect) {
        commonBounds = scaleToAspectRatio(commonBounds, width, height);
      }
  
      if (opts.normalize) {
        commonBounds = commonBounds.map(x => x / viewport.scale);
      }
  
      return commonBounds;
    }
  
    _commonToWorldBounds(commonBounds) {
      const [xMin, yMin, xMax, yMax] = commonBounds;
      const {
        viewport
      } = this.context;
      const topLeftWorld = viewport.unprojectPosition([xMin, yMax]);
      const bottomRightWorld = viewport.unprojectPosition([xMax, yMin]);
      return topLeftWorld.slice(0, 2).concat(bottomRightWorld.slice(0, 2));
    }
  
  }
  HeatmapLayer.layerName = 'HeatmapLayer';
  HeatmapLayer.defaultProps = defaultProps;
  //# sourceMappingURL=heatmap-layer.js.map