UNPKG

@doegis/core

Version:

DOE GIS API

3 lines (1 loc) 14.1 kB
import{_ as e}from"../../../../chunks/tslib.es6.js";import{estimateAttributesObjectSize as t,estimateFixedArraySize as r,estimateNumberByteSize as i}from"../../../../core/byteSizeEstimations.js";import{HandleOwner as a}from"../../../../core/HandleOwner.js";import{makeHandle as s}from"../../../../core/handleUtils.js";import o from"../../../../core/Logger.js";import{isSome as n,disposeMaybe as l,isNone as p,unwrap as d,applySome as m,mapSome as u}from"../../../../core/maybe.js";import{initial as h,sync as c,watch as y}from"../../../../core/reactiveUtils.js";import{pt2px as _}from"../../../../core/screenUtils.js";import{property as f}from"../../../../core/accessorSupport/decorators/property.js";import"../../../../core/accessorSupport/ensureType.js";import"../../../../core/arrayUtils.js";import{subclass as g}from"../../../../core/accessorSupport/decorators/subclass.js";import{c as F}from"../../../../chunks/vec3.js";import{c as R}from"../../../../chunks/vec3f64.js";import{projectPointToVector as b}from"../../../../geometry/projection.js";import{getResolutionForScale as v}from"../../../../geometry/support/scaleUtils.js";import{getObjectId as S}from"../../../../layers/graphics/dehydratedFeatures.js";import{convertFromPoint as w}from"../../../../layers/graphics/featureConversionUtils.js";import{OptimizedFeature as P}from"../../../../layers/graphics/OptimizedFeature.js";import j from"../../../../layers/graphics/OptimizedGeometry.js";import T from"../../../../layers/graphics/data/FeatureStore.js";import{isNumericField as V}from"../../../../layers/support/fieldUtils.js";import{generateGradient as x}from"../../../../renderers/support/heatmapUtils.js";import{DrapeSourceType as G}from"../interfaces.js";import{FeatureVisibilityFilter as M}from"./FeatureVisibilityFilter.js";import{DRAPED_Z as I}from"../../terrain/OverlayRenderer.js";import{Attribute as N}from"../../webgl-engine/lib/Attribute.js";import{ContentObjectType as O}from"../../webgl-engine/lib/ContentObjectType.js";import{DrapedHeatmapRenderer as A}from"../../webgl-engine/lib/DrapedHeatmapRenderer.js";import{Geometry as U}from"../../webgl-engine/lib/Geometry.js";import{DirtyOperation as C,DirtyState as E}from"../../webgl-engine/lib/ModelDirtyTypes.js";import{RenderGeometry as H}from"../../webgl-engine/lib/RenderGeometry.js";import{UpdatePolicy as D}from"../../webgl-engine/lib/UpdatePolicy.js";import{VertexAttribute as L}from"../../webgl-engine/lib/VertexAttribute.js";import{HeatmapDensityMaterial as W}from"../../webgl-engine/materials/HeatmapDensityMaterial.js";import{scaleBoundsPredicate as B,isScaleRangeActive as Z}from"../../../support/layerViewUtils.js";import{PixelType as z,PixelFormat as $}from"../../../webgl/enums.js";import{loadHeatmapTextureConfiguration as k}from"../../../webgl/heatmapTextureUtils.js";const q="esri.views.3d.layers.support.HeatmapFeatureProcessor",Y=o.getLogger(q),J=112;let K=class extends a{constructor(e){super(e),this.type="heatmap",this.preferredUpdatePolicy=D.ASYNC,this.dataExtent=null,this.drapeSourceType=G.Features,this._renderGeometries=new Map,this._fieldTotal=0,this._drapeSourceRenderer=null,this._dataType=z.HALF_FLOAT,this._pixelFormat=$.RGBA,this.initializePromise=Promise.resolve()}initialize(){this._featureStore=new T({geometryType:"esriGeometryPoint",hasZ:this.hasZ,hasM:this.hasM});const{dataType:e,samplingMode:t,pixelFormat:r,internalFormat:i}=k(this._renderView.renderingContext,Y);this._dataType=e,this._pixelFormat=r;const a=e!==z.FLOAT;this._drapeSourceRenderer=this.view.basemapTerrain.overlayManager.registerDrapeSource(this,A,{...this._rendererParameters,dataType:e,samplingMode:t,pixelFormat:r,internalFormat:i}),this._material=new W({usesHalfFloats:a}),this._materialWithField=new W({usesHalfFloats:a,isAttributeDriven:!0}),this._filterVisibility=new M({context:{layerView: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)),h),this.updatingHandles.addWhen((()=>this._materialParameters),(e=>this._forEachMaterial((t=>t.setParameters(e)))),h),this.updatingHandles.add((()=>this._rendererParameters),(e=>this._drapeSourceRenderer.set(e))),this.updatingHandles.add((()=>this._heatmapRendererField),(()=>{this._recreate()}),c),this.updatingHandles.add((()=>({fieldName:this._heatmapRendererFieldName,numeric:this._heatmapRendererFieldIsNumeric})),(({fieldName:e,numeric:t})=>{if(n(e)&&t){let t=0;this._featureStore.forEach((r=>t+=r.attributes[e]??0)),this._fieldTotal=t}else this._fieldTotal=this._featureStore.numFeatures}),h),this.handles.add([y((()=>({fieldName:this._heatmapRendererFieldName,field:this._heatmapRendererField})),(({fieldName:e,field:t})=>{e&&!t&&Y.warn(`Heatmap renderer field '${e}' for layer '${this.layer.title??this.layer.id}' not found`)})),y((()=>({field:this._heatmapRendererField,numeric:this._heatmapRendererFieldIsNumeric})),(({field:e,numeric:t})=>{n(e)&&!t&&Y.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`)})),s((()=>this.view.basemapTerrain.overlayManager.unregisterDrapeSource(this)))])}destroy(){this._renderGeometries.clear(),this._material=l(this._material),this._materialWithField=l(this._materialWithField),this._featureStore.clear(),this._featureStore=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?.resourceController?.memoryController?.memoryFactor??1,t=this.owner?.view?.qualitySettings,r=t?Math.ceil(t.heatmap.maxTotalNumberOfFeatures*e):0;return{minimumTotalNumberOfFeatures:0,maximumTotalNumberOfFeatures:r,maximumTotalNumberOfPrimitives:r*2,maximumNumberOfFeatures:r}}get hasZ(){return"hasZ"in this.layer&&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!B(r,e??0,t??0)}get usedMemory(){const e=this.usedMemoryPerFeature*this._featureStore.numFeatures,t=this._pixelFormat===$.RED?1:4,r=this._dataType===z.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(p(e))return 0;const a=t(e),s=i(),o=6;return o*r([0,0,0],s)+o*r([0,0],s)+(this._heatmapRendererFieldIsNumeric?o*s:0)+a}get loadedFeatures(){return this._featureStore.numFeatures}get unprocessedMemoryEstimate(){return 0}get performanceInfo(){return{core:{visible:this._visibleFeatures,missing:0,pending:0},elevationUpdating:!1,visibilityFrustum:!0,visibilityScale:!0}}get renderer(){return this._heatmapRenderer}get _overlayRenderer(){return this.view.basemapTerrain.overlayManager.renderer}get _overlaySpatialReference(){return d(this._overlayRenderer.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(p(e))return null;const{minDensity:t,maxDensity:r}=e;return{minDensity:t,maxDensity:r,fieldTotal:this._fieldTotal}}get _radiusParameter(){return m(this._heatmapRenderer,(({radius:e})=>({searchRadius:_(this._clampSearchRadius(e))})))}get _resolutionForScaleParameter(){return m(this._heatmapRenderer,(({referenceScale:e})=>({resolutionForScale:0===e?0:v(e,this.view.spatialReference)})))}get _colorRampParameter(){return m(this._heatmapRenderer,(e=>({colorRampData:x(e.colorStops)})))}get _pixelRatioParameter(){return{pixelRatio:this._densityMapPixelRatio}}get _densityMapPixelRatio(){const e=this.owner?.view?.resourceController?.memoryController?.memoryFactor??1;return(this.owner?.view?.qualitySettings.heatmap.pixelRatio??1)*Math.sqrt(e)}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 m(this._heatmapRenderer,(e=>e.field))}get _heatmapRendererField(){return m(this._heatmapRendererFieldName,(e=>this.layer.fieldsIndex.get(e)))}get _heatmapRendererFieldIsNumeric(){const e=this._heatmapRendererField;return!p(e)&&V(e)}get _isScaleRangeActive(){const{layer:e}=this;if(!("effectiveScaleRange"in e))return!1;const{minScale:t,maxScale:r}=e.effectiveScaleRange;return Z(t,r)}get _visibleFeatures(){let e=0;return this._renderGeometries.forEach((t=>{t.visible&&++e})),e}async whenGraphicBounds(){return null}computeAttachmentOrigin(){return null}highlight(){return Q}maskOccludee(){return Q}setObjectIdVisibility(){}refreshFilter(){this.filterVisibility.reapply()}_onLoadedFeaturesChange(e){if(!this._featuresArePoints)return;const{objectIdField:t}=this.layer;this._featureStore.removeManyById(e.removed.map((e=>S(e,t)))),this._featureStore.addMany(e.added.map((e=>{const r=new P(w(new j,e.geometry),e.attributes,m(e.centroid,(e=>w(new j,e))),S(e,t));return r.displayId=e.uid,r})));const r=e.added,i=e.removed;this._fieldTotal+=this._computeFieldTotalChange(r,i);const a=u(i,(({uid:e})=>{const t=this._renderGeometries.get(e);return this._renderGeometries.delete(e),t})),s=r.map((e=>{const t=this._pointGraphicToRenderGeometry(e);return this._renderGeometries.set(e.uid,t),t}));a.length>0&&this._drapeSourceRenderer.removeGeometries(a,C.REMOVE),s.length>0&&this._drapeSourceRenderer.addGeometries(s,C.ADD),(s.length>0||a.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=n(t)?this._materialWithField:this._material,i=R();b(e.geometry,i,this._overlaySpatialReference),i[2]=I;const a=[[L.POSITION,new N(i,i.length)]],s=this._heatmapRendererFieldIsNumeric;n(t)&&a.push([L.FEATUREATTRIBUTE,new N([s?e.attributes[t]??0:0],1)]);const o=new H(new U(r,a,null,null,O.Point),{layerUid:this.layer.uid,graphicUid:e.uid});return F(o.boundingSphere,i),o.visible=this.filterVisibility.defaultVisibility,o}_forEachMaterial(e){e(this._material),e(this._materialWithField)}_computeFieldTotalChange(e,t){if(p(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>J&&Y.warnOnce(`SceneView supports a maximum radius of ${J} pt for HeatmapRenderer.`),Math.min(e,J)}_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,E.VISIBILITY)}_setAllFeaturesVisibility(e){const t=[];for(const r of this._renderGeometries.values())r.visible!==e&&(t.push(r),r.visible=e);this._drapeSourceRenderer.modifyGeometries(t,E.VISIBILITY)}get test(){return{visibleFeatureCount:this._visibleFeatures}}};e([f()],K.prototype,"type",void 0),e([f({constructOnly:!0})],K.prototype,"owner",void 0),e([f()],K.prototype,"layer",null),e([f()],K.prototype,"featureStore",null),e([f()],K.prototype,"updating",null),e([f()],K.prototype,"updatingRemaining",null),e([f()],K.prototype,"suspendInfo",null),e([f()],K.prototype,"legendEnabled",null),e([f()],K.prototype,"filterVisibility",null),e([f()],K.prototype,"displayFeatureLimit",null),e([f()],K.prototype,"preferredUpdatePolicy",void 0),e([f()],K.prototype,"hasZ",null),e([f()],K.prototype,"hasM",null),e([f()],K.prototype,"dataExtent",void 0),e([f()],K.prototype,"view",null),e([f()],K.prototype,"fullOpacity",null),e([f()],K.prototype,"updatePolicy",null),e([f()],K.prototype,"drapeSourceType",void 0),e([f()],K.prototype,"scaleVisibilitySuspended",null),e([f()],K.prototype,"renderer",null),e([f()],K.prototype,"_featureStore",void 0),e([f()],K.prototype,"_filterVisibility",void 0),e([f()],K.prototype,"_overlayRenderer",null),e([f()],K.prototype,"_overlaySpatialReference",null),e([f()],K.prototype,"_rendererParameters",null),e([f()],K.prototype,"_materialParameters",null),e([f()],K.prototype,"_densityParameters",null),e([f()],K.prototype,"_radiusParameter",null),e([f()],K.prototype,"_resolutionForScaleParameter",null),e([f()],K.prototype,"_colorRampParameter",null),e([f()],K.prototype,"_pixelRatioParameter",null),e([f()],K.prototype,"_densityMapPixelRatio",null),e([f()],K.prototype,"_renderGeometries",void 0),e([f()],K.prototype,"_material",void 0),e([f()],K.prototype,"_materialWithField",void 0),e([f()],K.prototype,"_renderView",null),e([f()],K.prototype,"_featuresArePoints",null),e([f()],K.prototype,"_loadedPointGraphics",null),e([f()],K.prototype,"_heatmapRenderer",null),e([f()],K.prototype,"_heatmapRendererFieldName",null),e([f()],K.prototype,"_heatmapRendererField",null),e([f()],K.prototype,"_heatmapRendererFieldIsNumeric",null),e([f()],K.prototype,"_fieldTotal",void 0),e([f()],K.prototype,"_drapeSourceRenderer",void 0),e([f()],K.prototype,"_isScaleRangeActive",null),K=e([g(q)],K);const Q=s();export{K as HeatmapFeatureProcessor,J as MAX_RADIUS_PT};