UNPKG

@arcgis/core

Version:

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

3 lines (2 loc) • 15.6 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */ import{__decorate as e}from"tslib";import{equals as t}from"../../../core/arrayUtils.js";import"../../../core/has.js";import{removeMaybe as i,abortMaybe as s}from"../../../core/maybe.js";import{debounce as r,ignoreAbortErrors as l,throwIfAborted as n}from"../../../core/promiseUtils.js";import{watch as a,sync as o,when as u,whenOnce as d}from"../../../core/reactiveUtils.js";import{addFrameTask as h}from"../../../core/scheduling.js";import{signal as c}from"../../../core/signal.js";import{Seconds as p,secondsFromMilliseconds as m}from"../../../core/time.js";import{property as g,subclass as f}from"../../../core/accessorSupport/decorators.js";import{projectOrLoad as _}from"../../../geometry/projectionUtils.js";import y from"../../../geometry/SpatialReference.js";import{fromExtent as v,intersection as w,toExtent as T,create as S,intersects as b}from"../../../geometry/support/aaBoundingRect.js";import{getInfo as R}from"../../../geometry/support/spatialReferenceUtils.js";import x from"../../../symbols/support/ElevationInfo.js";import L from"./SubView3D.js";import{getFeatureTileId as A}from"./support/FeatureTileDescriptor.js";import{makeScheduleFunction as E}from"./support/makeScheduleFunction.js";import{debugFlags as j}from"../support/debugFlags.js";import{tileFilterDistance as M,scaleThresholdForLoadingAllTiles as P,defaultTransitionDuration as U,transitionDurationFactor as C,seamlessTransitionEnabled as I,densityFactor as W,loadAllTilesDensityFactor as F,averageLoadingTimeSmoothingFactor as D,fadeOutTime as k,fadeInTime as q,minimumTracingResolution as O}from"../support/flow/constants.js";import{isFullExtent as V,wrappedWidth as G,FlowQuery3D as B}from"../support/flow/FlowQuery3D.js";import{FlowWorkerHandle as H}from"../support/flow/FlowWorkerHandle.js";import{materialParametersFromRenderer as z,createStreamlineGeometry as N}from"../support/flow/geometryUtils.js";import{boundingRectOfTiles as Q}from"../support/flow/loadUtils.js";import{StreamlineResources3DOverlay as J}from"../support/flow/StreamlineResources3DOverlay.js";import{StreamlineResources3DShape as K}from"../support/flow/StreamlineResources3DShape.js";import{webMercatorWorldExtent as X}from"../terrain/TerrainConst.js";import{descendantsAtLevel as Y,tilesAreRelated as Z}from"../terrain/tileUtils.js";import{isScreenSizePerspectiveEnabled as $}from"../webgl-engine/lib/screenSizePerspectiveUtils.js";import{RibbonLineMaterial as ee}from"../webgl-engine/materials/RibbonLineMaterial.js";import{hasLayerBasedScaleVisibility as te,isInEffectiveScaleRange as ie}from"../../support/layerViewUtils.js";import{TaskPriority as se}from"../../support/Scheduler.js";import{simulationSettingsEqual as re,getPositions as le,getFlowSimulationSettings as ne}from"../../support/flow/utils.js";let ae=class extends L{constructor(e){super(e),this.type="flow",this.renderedTiles=null,this.requireLoad=!1,this.workerHandle=null,this.frameTask=null,this._averageLoadingTime=p(0),this._abortController=null,this._loadingState="ready-to-load",this._tilesUpdateIsWaiting=!1,this._debugAllowAutoLoading=c(!0),this.emissiveStrength=0,this._overrideMaterialParameters=null,this._overrideSimulationSettings=null,this._overrideSeamlessTransitionEnabled=null,this._updateTask=null,this._debouncedTileUpdate=r(async()=>{const{allTiles:e}=this.surface,t=this._getTileFilterFunction(),i=new Set;function*s(s){for(let r=0;r<e.length;++r){const l=e.at(r);t(l)&&i.add(l),s.madeProgress(),s.done&&(s=yield)}}await this.frameTask.scheduleGenerator(s),this.renderedTiles=i})}initialize(){const{surface:e,view:t}=this,{resourceController:i}=t;this.workerHandle=new H(E(i)),this.frameTask=i.scheduler.registerTask(se.FLOW_GENERATOR),this._updateTask=h({update:()=>this._update()}),this.addHandles([a(()=>this._simulationSettings,()=>this.triggerLoad(),{sync:!0,equals:(e,t)=>null==e&&null==t||null!=e&&null!=t&&re(e,t)}),a(()=>{const{elevationInfo:e}=this;return[this._clippingArea,this.visible,this._draped,this.view.state.contentPixelRatio,this.view.viewingMode,e?.mode,e?.offset,e?.unit,this._effectiveDensity]},()=>this.triggerLoad(),o),u(()=>!this.view.animationsEnabled,()=>{const{_resources:e,_lastResources:t}=this;null!=e&&(e.startTime=he),null!=t&&(t.startTime=he)},o),a(()=>this._materialParameters,e=>{this._resources?.setMaterialParameters(e),this._lastResources?.setMaterialParameters(e)}),u(()=>e.allTilesCreated,()=>this._triggerTilesUpdate(),o),t.enableFeatureTiles(),a(()=>[this._dataBounds,this._featureTilesBounds,this.loadAllTiles],()=>this._triggerTilesUpdate()),a(()=>this._flowRenderer,(e,t)=>{const i=t?.visualVariables??[],s=e?.visualVariables??[];s.length===i.length&&s.every((e,t)=>e.type===i[t].type)||this.clear()}),u(()=>!t.featureTiles?.updating,()=>{this._triggerTilesUpdate()})]),this._triggerTilesUpdate()}destroy(){this._updateTask=i(this._updateTask),this.abort(),this.clear(),this.notifyChange("updating")}abort(){this._abortController=s(this._abortController),this.requireLoad=!1}get _clippingArea(){const e=_(this.view.clippingArea,this.surface.spatialReference).geometry;return null==e?null:v(e)}get _dataBounds(){const e=this._fullExtentSurfaceSpatialReference;return null==e?null:v(e)}get _fullExtentSurfaceSpatialReference(){return _(this.layer.fullExtent,this.surface.spatialReference).geometry}get _draped(){return"on-the-ground"===this.elevationInfo.mode}get extent(){if(this.loadAllTiles)return ce(this._fullExtentSurfaceSpatialReference);const{spatialReference:e}=this.surface;let t=this.renderedTiles;if(null==e||null==t)return null;const i=this.view.terrainLevel;if(null!=i){const e=new Set;t.forEach(t=>{Math.abs(i-t.level)<M&&e.add(t)}),t=e}const s=Q(t,this.spatialReferenceInfo);return null==s?null:(w(s,this._clippingArea,s),ce(T(s,e)))}get loadAllTiles(){return this.view.scale>(j.FLOW_GLOBAL_SCALE_THRESHOLD??P)}get isDataGlobal(){const{extent:e,spatialReferenceInfo:t}=this;return null!=e&&V(e.xmin,e.xmax,t)}get loadAllTilesLevel(){const{tilingScheme:e}=this.surface;return Math.min(Math.ceil(e.levelAtScale(j.FLOW_GLOBAL_SCALE_THRESHOLD??P)),e.getMaxLod())}get targetTiles(){const e=new Map;if(this.loadAllTiles){const{_dataBounds:t}=this;if(null==t)return e;const i=S(),s=this.loadAllTilesLevel,r=this.surface.tilingScheme,l=r.rootTilesInExtent(t).flatMap(e=>Y(e,s));for(const n of l){const[l,a,o]=n;r.getExtent(s,a,o,i),ue(t,i)&&e.set(A(s,a,o),n)}return e}const{renderedTiles:t}=this;for(const i of t??[])e.set(i.key,i.lij);return e}get _featureTilesBounds(){const e=this.view.featureTiles?.filterExtent,t=_(e,this.surface.spatialReference).geometry;return null==t?null:v(t)}get _flowRenderer(){const e=this.layer.renderer;return"flow"!==e?.type?null:e}get _materialParameters(){return{...z(this._flowRenderer,this.layerView.fullOpacity,this.emissiveStrength),...this._overrideMaterialParameters,hasSlicePlane:this.layerView.slicePlaneEnabled,screenSizePerspective:!this._draped&&"screenSizePerspectiveEnabled"in this.layer&&$(this.layer.screenSizePerspectiveEnabled)?this.view.screenSizePerspective.parameters:null}}get _opacity(){return this.layerView.fullOpacity}get _seamlessTransitionWaitingTime(){const{_averageLoadingTime:e}=this;return p(0===e?U:this._averageLoadingTime*C)}get _transitionEnabled(){return this.view.qualitySettings.flow.transitionEnabled}get _seamlessTransitionEnabled(){return!!this._transitionEnabled&&(null!=this._overrideSeamlessTransitionEnabled?this._overrideSeamlessTransitionEnabled:I)}get _tracingResolution(){const{extent:e}=this;if(!e)return[0,0];const t=G(e.xmin,e.xmax,this.spatialReferenceInfo?.valid)/(e.ymax-e.ymin),[i,s]=this.view.size;let r,l;i<s?(r=i,l=i/t):(r=s*t,l=s);const n=O,a=this.view.qualitySettings.flow.maxTracingResolution,o=Math.max(1,n/Math.min(r,l)),u=o*Math.min(1,a/Math.max(r*o,l*o));return[Math.round(r*u),Math.round(l*u)]}get visible(){const e=this._flowRenderer?.color;return this.visibleAtCurrentScale&&this.layer.effectiveVisible&&this._opacity>0&&(null==e||e.a>0)}get _effectiveDensity(){const{_simulationSettings:e}=this;if(null==e)return 0;const t=e.density*this.view.quality;return e.lineSpacing/Math.sqrt(t)<e.lineCollisionWidth?(e.lineSpacing/e.lineCollisionWidth)**2:t}get elevationInfo(){return("elevationInfo"in this.layer?this.layer.elevationInfo:void 0)??oe}startPositions(e){if(!this._seamlessTransitionEnabled)return[];const{_flowRenderer:t,_resources:i}=this;return null==t||null==i?[]:le(i.streamlines,i.query,e,t.flowSpeed)}get needsMagnitude(){return this._flowRenderer?.hasVisualVariables()??!1}get spatialReferenceInfo(){return R(this.surface.spatialReference)}get loadingState(){return this._loadingState}get loadRequirementsMet(){return null!=this.renderedTiles&&(this.renderedTiles.size>0||this.loadAllTiles)&&null!=this.extent}hasWork(){return null==this.extent||this.updatingHandles.updating||this.requireLoad||"before-transition"===this._loadingState}get updating(){return this._debugAllowAutoLoading.value&&this.visible&&!(this.destroyed||this.destroying)&&this.hasWork()}get visibleAtCurrentScale(){return!te()||ie(this.layer.effectiveScaleRange,this.view.scale)}get _simulationSettings(){const{_flowRenderer:e,_overrideSimulationSettings:t}=this;if(null==e)return null;let i=ne(e);return i.segmentLength=i.lineCollisionWidth/2,i.onlyForwardTracing=!1,i.maxNumberOfStreamlines=this.view.qualitySettings.flow.maxTotalNumberOfStreamlines,i.density*=W,this.loadAllTiles&&this.isDataGlobal&&(i.density*=F),null!=t&&(i={...i,...t}),i}getSimulationSettings(e){const{_simulationSettings:t,spatialReferenceInfo:i}=this;if(null==t)return null;const s="global"===this.view.viewingMode&&null!=i&&V(e.extent.xmin,e.extent.xmax,i);return{...t,wrapAround:s,density:this._effectiveDensity}}get surface(){return this.view.basemapTerrain}doRefresh(){}clear(){this._resources?.detach(),this._resources=null,this._lastResources?.detach(),this._lastResources=null,this._loadingState="ready-to-load"}_update(){const e=this._time;this._lastResources?.hasFadedOut(e)&&this._lastResources.detach();const t=this._nextStateForTransition(e);if(!this.requireLoad||this.updatingHandles.updating||"ready-to-load"!==t||!this.loadRequirementsMet)return void(this._loadingState=t);this._loadingState="loading";const i=async()=>{const t=this._time,i=this._seamlessTransitionEnabled&&null!=this._resources?p(e+this._seamlessTransitionWaitingTime):e;await this._load(i);const s=p((this._time-t)/1e3);this._updateAverageLoadingTime(s)};this.updatingHandles.addPromise(l(i())),this.requireLoad=!1}_updateAverageLoadingTime(e){const t=D;this._averageLoadingTime=p(t*e+(1-t)*this._averageLoadingTime)}triggerLoad(){this._debugAllowAutoLoading.value&&(this.visible?this.requireLoad=!0:this.clear())}get _time(){return m(this.layerView.view.stage.renderer.renderContext.time)}async _load(e){const{extent:t,view:i}=this;if(!this.visible)return void this.clear();if(null==t)return void(this._loadingState="ready-to-load");this._transitionEnabled||(this._lastResources?.detach(),this._lastResources=null,this._resources?.detach(),this._resources=null);const s=new B(t,this.layerView.timeExtent,this._tracingResolution,i.state.contentPixelRatio,e);null==this._abortController&&(this._abortController=new AbortController);const r=this._abortController;try{const t=await this._loadStreamlines(s,r.signal);if(n(r.signal),null!=t){this._lastResources?.detach(),this._lastResources=this._resources,this._resources=t;const i=this._getStartTime(e);null!=this._lastResources&&(this._lastResources.endTime=i),this._resources.startTime=i,this.view.animationsEnabled||(this._lastResources?.detach(),this._lastResources=null),await t.attach(),this._loadingState=this._seamlessTransitionEnabled?"before-transition":"transitioning"}else this._loadingState="ready-to-load"}catch(l){this._loadingState="ready-to-load"}}async _loadStreamlines(e,t){const i=await this.fetchDataAndGenerateStreamlines(e,t);if(null==i)return null;const{geometries:s,material:r}=await this._createGeometry(e,i);return this._draped?new J(e,i,r,s,this.layerView):new K(e,i,r,s,this.view)}async fetchDataAndGenerateStreamlines(e,t){return null}async _createGeometry(e,t){const i=new ee(this._materialParameters,this.view.state.isGlobal),s=new Array,{elevationInfo:r,_draped:l,view:n}=this;function*a(a){for(let o=0;o<t.length;++o)s.push(N(n,e,t[o],r,i,l)),a.madeProgress(),a.done&&(a=yield)}return await this.frameTask.scheduleGenerator(a),{geometries:s,material:i}}_triggerTilesUpdate(){if(this._tilesUpdateIsWaiting)return;this._tilesUpdateIsWaiting=!0;const e=async()=>{await d(()=>this.view.stationary),this._tilesUpdateIsWaiting=!1,await this._debouncedTileUpdate()};this.updatingHandles.addPromise(l(e()))}_getTileFilterFunction(){const{_dataBounds:e,view:i,_featureTilesBounds:s,loadAllTiles:r}=this;if(r){const{loadAllTilesLevel:t}=this;return i=>i.level===t&&ue(e,i.extent)}const l=t=>t.rendered&&t.visible&&ue(e,t.extent),{featureTiles:n}=i;if(!n)return l;const a=n.tiles.filter(e=>e.measures.visible);return e=>l(e)&&ue(s,e.extent)&&a.some(({lij:i})=>t(i,e.lij)||Z(i,e.lij))}_nextStateForTransition(e){const{_resources:t}=this;if(null==this._flowRenderer||null==t||"ready-to-load"===this._loadingState||"loading"===this._loadingState)return this._loadingState;const i=t.startTime;return e<i?"before-transition":e<i+k?"transitioning":"ready-to-load"}_getStartTime(e){if(!this.view.animationsEnabled)return he;const t=this._time;return p(t>e?t:e)}get usedMemory(){return(this._lastResources?.usedMemory??0)+(this._resources?.usedMemory??0)}get test(){}};e([g()],ae.prototype,"type",void 0),e([g()],ae.prototype,"renderedTiles",void 0),e([g()],ae.prototype,"_resources",void 0),e([g()],ae.prototype,"_lastResources",void 0),e([g()],ae.prototype,"requireLoad",void 0),e([g()],ae.prototype,"_averageLoadingTime",void 0),e([g()],ae.prototype,"_loadingState",void 0),e([g()],ae.prototype,"emissiveStrength",void 0),e([g()],ae.prototype,"_clippingArea",null),e([g()],ae.prototype,"_dataBounds",null),e([g()],ae.prototype,"_fullExtentSurfaceSpatialReference",null),e([g()],ae.prototype,"_draped",null),e([g()],ae.prototype,"extent",null),e([g()],ae.prototype,"loadAllTiles",null),e([g()],ae.prototype,"isDataGlobal",null),e([g()],ae.prototype,"loadAllTilesLevel",null),e([g()],ae.prototype,"targetTiles",null),e([g()],ae.prototype,"_featureTilesBounds",null),e([g()],ae.prototype,"_flowRenderer",null),e([g()],ae.prototype,"_materialParameters",null),e([g()],ae.prototype,"_opacity",null),e([g()],ae.prototype,"_seamlessTransitionWaitingTime",null),e([g()],ae.prototype,"_transitionEnabled",null),e([g()],ae.prototype,"_seamlessTransitionEnabled",null),e([g()],ae.prototype,"_tracingResolution",null),e([g()],ae.prototype,"visible",null),e([g()],ae.prototype,"_effectiveDensity",null),e([g()],ae.prototype,"elevationInfo",null),e([g()],ae.prototype,"needsMagnitude",null),e([g()],ae.prototype,"spatialReferenceInfo",null),e([g()],ae.prototype,"loadingState",null),e([g()],ae.prototype,"updating",null),e([g()],ae.prototype,"visibleAtCurrentScale",null),e([g()],ae.prototype,"_overrideMaterialParameters",void 0),e([g()],ae.prototype,"_overrideSimulationSettings",void 0),e([g()],ae.prototype,"_overrideSeamlessTransitionEnabled",void 0),e([g()],ae.prototype,"_simulationSettings",null),e([g()],ae.prototype,"surface",null),ae=e([f("esri.views.3d.layers.FlowSubView3D")],ae);const oe=new x({mode:"on-the-ground"});function ue(e,t){return null==e||null==t||b(e,t)}const de=T(X,y.WebMercator),he=p(-q);function ce(e){return null!=e&&e.spatialReference.isWebMercator?e?.intersection(de):e}export{ae as default};