UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

3 lines (2 loc) • 13.9 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */ import{__decorate as e}from"tslib";import{isSome as t}from"../../../../core/arrayUtils.js";import{makeHandle as r}from"../../../../core/handleUtils.js";import"../../../../core/has.js";import i from"../../../../core/Logger.js";import{estimateAttributesMemory as a,estimateFixedArrayMemory as s,estimateNumberMemory as o}from"../../../../core/memoryEstimations.js";import{EsriPromise as n}from"../../../../core/Promise.js";import{initial as l,sync as d,watch as p}from"../../../../core/reactiveUtils.js";import{pt2px as u}from"../../../../core/screenUtils.js";import{property as h,subclass as m}from"../../../../core/accessorSupport/decorators.js";import{create as c}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{UpdatingHandles as y}from"../../../../core/support/UpdatingHandles.js";import{projectPointToVector as _}from"../../../../geometry/projection/projectPointToVector.js";import{getContinuousIndexArray as g}from"../../../../geometry/support/Indices.js";import{getResolutionForScale as f}from"../../../../geometry/support/scaleUtils.js";import{getObjectId as R}from"../../../../layers/graphics/dehydratedFeatures.js";import{convertFromPoint as F}from"../../../../layers/graphics/featureConversionUtils.js";import{OptimizedFeature as v}from"../../../../layers/graphics/OptimizedFeature.js";import b from"../../../../layers/graphics/data/FeatureStore.js";import{isNumericField as w}from"../../../../layers/support/fieldUtils.js";import{generateGradient as S}from"../../../../renderers/support/heatmapUtils.js";import{DisplayFeatureLimit as P}from"../graphics/DisplayFeatureLimit.js";import{GraphicsCorePerformanceInfo as j}from"../graphics/GraphicsCorePerformanceInfo.js";import{FeatureVisibilityFilter as G}from"./FeatureVisibilityFilter.js";import{emptyHighlightHandle as V}from"./highlightUtils.js";import{drapedZ as x}from"../../terrain/OverlayRenderer.js";import{Attribute as M}from"../../webgl-engine/lib/Attribute.js";import{DrapedHeatmapRenderer as T}from"../../webgl-engine/lib/DrapedHeatmapRenderer.js";import{Geometry as I}from"../../webgl-engine/lib/Geometry.js";import{GeometryBaseInstance as A}from"../../webgl-engine/lib/GeometryBaseInstance.js";import{RenderGeometry as N}from"../../webgl-engine/lib/RenderGeometry.js";import{HeatmapDensityMaterial as H}from"../../webgl-engine/materials/HeatmapDensityMaterial.js";import{scaleBoundsPredicate as U,isScaleRangeActive as O}from"../../../support/layerViewUtils.js";import{PixelType as L}from"../../../webgl/enums.js";import{loadHeatmapTextureConfiguration as C,fallBackHeatmapConfiguration as D}from"../../../webgl/heatmapTextureUtils.js";const E=112;let W=class extends n{constructor(e){super(e),this.type="heatmap",this.preferredUpdatePolicy=0,this.dataExtent=null,this.drapeSourceType=1,this._renderGeometries=new Map,this._fieldTotal=0,this._drapeSourceRenderer=null,this._dataType=L.HALF_FLOAT,this._pixelFormat=6408,this._baseInstance=new A([]),this._updatingHandles=new y}initialize(){let e;try{e=C(this._renderView.renderingContext,i.getLogger(this))}catch(m){this.addResolvingPromise(Promise.reject(m)),e=D}const{dataType:t,samplingMode:a,pixelFormat:s,internalFormat:o}=e;this._featureStore=new b({geometryType:"esriGeometryPoint",hasZ:this.hasZ,hasM:this.hasM}),this._dataType=t,this._pixelFormat=s;const n=t!==L.FLOAT,u=this.view.overlayManager,h={...this._rendererParameters,stage:this.view.stage,dataType:t,samplingMode:a,pixelFormat:s,internalFormat:o,rendererContext:u.renderer,drapeSource:this};this._drapeSourceRenderer=new T(h),u.registerDrapeSource(this,this._drapeSourceRenderer),this._material=new H({usesHalfFloats:n}),this._materialWithField=new H({usesHalfFloats:n,isAttributeDriven:!0}),this._filterVisibility=new G({context:{configuration:this.owner,featureStore:this.featureStore,getFeatureCount:()=>this._loadedPointGraphics.length,setAllFeaturesVisibility:e=>this._setAllFeaturesVisibility(e),clearFeaturesVisibility:()=>this._setAllFeaturesVisibility(!0),updateFeatureVisibilities:e=>this._updateFeatureVisibilities(e)}}),this._updatingHandles.addOnCollectionChange(()=>this._loadedPointGraphics,e=>this._onLoadedFeaturesChange(e),l),this._updatingHandles.addWhen(()=>this._materialParameters,e=>this._forEachMaterial(t=>t.setParameters(e)),l),this._updatingHandles.add(()=>this._rendererParameters,e=>this._drapeSourceRenderer.set(e)),this._updatingHandles.add(()=>this._heatmapRendererField,()=>{this._recreate()},d),this._updatingHandles.add(()=>({fieldName:this._heatmapRendererFieldName,numeric:this._heatmapRendererFieldIsNumeric}),({fieldName:e,numeric:t})=>{if(null!=e&&t){let t=0;this._featureStore.forEach(r=>t+=r.attributes[e]??0),this._fieldTotal=t}else this._fieldTotal=this._featureStore.numFeatures},l),this.addHandles([p(()=>({fieldName:this._heatmapRendererFieldName,field:this._heatmapRendererField}),({fieldName:e,field:t})=>{e&&!t&&i.getLogger(this).warn(`Heatmap renderer field '${e}' for layer '${this.layer.title??this.layer.id}' not found`)}),p(()=>({field:this._heatmapRendererField,numeric:this._heatmapRendererFieldIsNumeric}),({field:e,numeric:t})=>{null==e||t||i.getLogger(this).warn(`Heatmap renderer field '${e.name}' for layer '${this.layer.title??this.layer.id}' does not contain numeric values and cannot be used to drive the heatmap density`)}),r(()=>this.view.overlayManager.unregisterDrapeSource(this))])}destroy(){this._renderGeometries.clear(),this._material=null,this._materialWithField=null,this._featureStore.clear(),this._featureStore=null,this._updatingHandles.destroy(),this._baseInstance=null}get layer(){return this.owner.layer}get featureStore(){return this._featureStore}get updating(){return this._updatingHandles.updating||this.filterVisibility.updating}get updatingRemaining(){return 0}get suspendInfo(){return{}}get legendEnabled(){return!0}get filterVisibility(){return this._filterVisibility}get displayFeatureLimit(){const e=this.owner?.view?.quality??1,t=this.owner?.view?.qualitySettings,r=t?Math.ceil(t.graphics3D.maxTotalNumberOfFeatures*e):0;return new P(r*6,r)}get hasZ(){return"hasZ"in this.layer&&!0===this.layer.hasZ}get hasM(){return"hasM"in this.layer&&this.layer.hasM}get view(){return this.owner.view}get fullOpacity(){return this.owner.fullOpacity}get updatePolicy(){return this.owner.updatePolicy}get scaleVisibilitySuspended(){if(!this._isScaleRangeActive)return!1;const{minScale:e,maxScale:t}=this.layer.effectiveScaleRange,{scale:r}=this.view;return!U(r,e??0,t??0)}get usedMemory(){const e=this.usedMemoryPerFeature*this._featureStore.numFeatures,t=6403===this._pixelFormat?1:4,r=this._dataType===L.FLOAT?4:2,i=Math.ceil((this._overlayRenderer?.overlays[0]?.resolution??0)*this._densityMapPixelRatio)??0;return i*i*t*r+e}get usedMemoryPerFeature(){const e=this._loadedPointGraphics.find(()=>!0);if(null==e)return 0;const t=a(e),r=6;return r*s([0,0,0],o)+r*s([0,0],o)+(this._heatmapRendererFieldIsNumeric?r*o:0)+t}get loadedFeatures(){return this._featureStore.numFeatures}get unprocessedMemoryEstimate(){return 0}get performanceInfo(){return new j(this._renderGeometries.size,this._visibleFeatures,0,0)}get renderer(){return this._heatmapRenderer}get _overlayRenderer(){return this.view.overlayManager.renderer}get _overlaySpatialReference(){return this.view.overlayManager.spatialReference}get _rendererParameters(){return{...this._radiusParameter,...this._densityParameters,...this._colorRampParameter,...this._pixelRatioParameter}}get _materialParameters(){return{...this._radiusParameter,...this._resolutionForScaleParameter}}get _densityParameters(){const e=this._heatmapRenderer;if(null==e)return null;const{minDensity:t,maxDensity:r}=e;return{minDensity:t,maxDensity:r,fieldTotal:this._fieldTotal}}get _radiusParameter(){const e=this._heatmapRenderer;return e?{searchRadius:u(this._clampSearchRadius(e.radius))}:null}get _resolutionForScaleParameter(){const e=this._heatmapRenderer;if(!e)return null;const{referenceScale:t}=e;return{resolutionForScale:0===t?0:f(t,this.view.spatialReference)}}get _colorRampParameter(){const e=this._heatmapRenderer;return e?{colorRampData:S(e.colorStops)}:null}get _pixelRatioParameter(){return{pixelRatio:this._densityMapPixelRatio}}get _densityMapPixelRatio(){return this.owner?.view?.qualitySettings.heatmap.pixelRatio??1}get _renderView(){return this.view.stage.renderView}get _featuresArePoints(){return"point"===this.layer.geometryType}get _loadedPointGraphics(){return this.owner.loadedGraphics}get _heatmapRenderer(){const e=this.layer.renderer;return"heatmap"===e?.type?e:null}get _heatmapRendererFieldName(){return this._heatmapRenderer?.field}get _heatmapRendererField(){const e=this._heatmapRendererFieldName;return null!=e?this.layer.fieldsIndex.get(e):null}get _heatmapRendererFieldIsNumeric(){const e=this._heatmapRendererField;return null!=e&&w(e)}get _isScaleRangeActive(){const{layer:e}=this;if(!("effectiveScaleRange"in e))return!1;const{minScale:t,maxScale:r}=e.effectiveScaleRange;return O(t,r)}get _visibleFeatures(){return Array.from(this._renderGeometries.values()).reduce((e,{visible:t})=>e+(t?1:0),0)}async whenGraphicBounds(){return null}computeAttachmentOrigin(){return null}highlightByGraphics(){return V}highlightByObjectIds(){return V}maskOccludee(){return r()}setObjectIdVisibility(){}refreshFilter(){this.filterVisibility.reapply()}_onLoadedFeaturesChange(e){if(!this._featuresArePoints)return;const{objectIdField:r}=this.layer;this._featureStore.removeManyById(e.removed.map(e=>R(e,r))),this._featureStore.addMany(e.added.map(e=>{const{attributes:t,centroid:i,geometry:a}=e,s=new v(F(a),t,i?F(i):null,R(e,r));return s.displayId=e.uid,s}));const i=e.added,a=e.removed;this._fieldTotal+=this._computeFieldTotalChange(i,a);const s=a.map(({uid:e})=>{const t=this._renderGeometries.get(e);return this._renderGeometries.delete(e),t}).filter(t),o=i.map(e=>{const t=this._pointGraphicToRenderGeometry(e);return this._renderGeometries.set(e.uid,t),t});s.length>0&&this._drapeSourceRenderer.removeGeometries(s,2),o.length>0&&this._drapeSourceRenderer.addGeometries(o,0),(o.length>0||s.length>0)&&(this.filterVisibility.reapply(),this._renderView.requestRender())}_recreate(){if(!this._loadedPointGraphics)return;const e=this._loadedPointGraphics.toArray();this._onLoadedFeaturesChange({added:e,removed:e})}_pointGraphicToRenderGeometry(e){const t=this._heatmapRendererFieldName,r=null!=t?this._materialWithField:this._material,i=c();_(e.geometry,i,this._overlaySpatialReference),i[2]=x;const a=g(1),s=[["position",new M(i,a,i.length)]],o=this._heatmapRendererFieldIsNumeric;null!=t&&s.push(["featureAttribute",new M([o?e.attributes[t]??0:0],a,1)]);const n=new N(new I(r,s,null,1,null,void 0,this._baseInstance),{layerViewUid:this.owner.layerViewUid,graphicUid:e.uid});return n.visible=this.filterVisibility.defaultVisibility,n}_forEachMaterial(e){e(this._material),e(this._materialWithField)}_computeFieldTotalChange(e,t){if(null==this._heatmapRendererFieldName||!this._heatmapRendererFieldIsNumeric)return e.length-t.length;const r=this._heatmapRendererFieldName,i=(e,t)=>e+(t.attributes[r]??0);return e.reduce(i,0)-t.reduce(i,0)}_clampSearchRadius(e){return e>E&&i.getLogger(this).warnOnce(`SceneView supports a maximum radius of ${E} pt for HeatmapRenderer.`),Math.min(e,E)}_updateFeatureVisibilities(e){const t=[];this._featureStore.forEach(({objectId:r,displayId:i})=>{const a=e(r),s=this._renderGeometries.get(i);s&&s.visible!==a&&(t.push(s),s.visible=a)}),this._drapeSourceRenderer.modifyGeometries(t,1)}_setAllFeaturesVisibility(e){const t=[];for(const r of this._renderGeometries.values())r.visible!==e&&(t.push(r),r.visible=e);this._drapeSourceRenderer.modifyGeometries(t,1)}get test(){}};e([h()],W.prototype,"type",void 0),e([h({constructOnly:!0})],W.prototype,"owner",void 0),e([h()],W.prototype,"layer",null),e([h()],W.prototype,"featureStore",null),e([h()],W.prototype,"updating",null),e([h()],W.prototype,"updatingRemaining",null),e([h()],W.prototype,"suspendInfo",null),e([h()],W.prototype,"legendEnabled",null),e([h()],W.prototype,"filterVisibility",null),e([h()],W.prototype,"displayFeatureLimit",null),e([h()],W.prototype,"preferredUpdatePolicy",void 0),e([h()],W.prototype,"hasZ",null),e([h()],W.prototype,"hasM",null),e([h()],W.prototype,"dataExtent",void 0),e([h()],W.prototype,"view",null),e([h()],W.prototype,"fullOpacity",null),e([h()],W.prototype,"updatePolicy",null),e([h()],W.prototype,"drapeSourceType",void 0),e([h()],W.prototype,"scaleVisibilitySuspended",null),e([h()],W.prototype,"renderer",null),e([h()],W.prototype,"_featureStore",void 0),e([h()],W.prototype,"_filterVisibility",void 0),e([h()],W.prototype,"_overlayRenderer",null),e([h()],W.prototype,"_overlaySpatialReference",null),e([h()],W.prototype,"_rendererParameters",null),e([h()],W.prototype,"_materialParameters",null),e([h()],W.prototype,"_densityParameters",null),e([h()],W.prototype,"_radiusParameter",null),e([h()],W.prototype,"_resolutionForScaleParameter",null),e([h()],W.prototype,"_colorRampParameter",null),e([h()],W.prototype,"_pixelRatioParameter",null),e([h()],W.prototype,"_densityMapPixelRatio",null),e([h()],W.prototype,"_renderGeometries",void 0),e([h()],W.prototype,"_material",void 0),e([h()],W.prototype,"_materialWithField",void 0),e([h()],W.prototype,"_renderView",null),e([h()],W.prototype,"_featuresArePoints",null),e([h()],W.prototype,"_loadedPointGraphics",null),e([h()],W.prototype,"_heatmapRenderer",null),e([h()],W.prototype,"_heatmapRendererFieldName",null),e([h()],W.prototype,"_heatmapRendererField",null),e([h()],W.prototype,"_heatmapRendererFieldIsNumeric",null),e([h()],W.prototype,"_fieldTotal",void 0),e([h()],W.prototype,"_drapeSourceRenderer",void 0),e([h()],W.prototype,"_isScaleRangeActive",null),W=e([m("esri.views.3d.layers.support.HeatmapFeatureProcessor")],W);export{W as HeatmapFeatureProcessor,E as maxRadiusPt};