@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
3 lines (2 loc) • 7.57 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */
import{__decorate as e}from"tslib";import t from"../../../../core/Accessor.js";import s from"../../../../core/Collection.js";import i from"../../../../core/Logger.js";import{removeMaybe as r}from"../../../../core/maybe.js";import n from"../../../../core/PooledArray.js";import{watch as l,syncAndInitial as o,sync as a}from"../../../../core/reactiveUtils.js";import{signal as u}from"../../../../core/signal.js";import{property as h,subclass as d}from"../../../../core/accessorSupport/decorators.js";import{create as m,intersects as p}from"../../../../geometry/support/aaBoundingRect.js";import{FeatureTileDescriptor as c,getFeatureTileId as _}from"./FeatureTileDescriptor.js";import{FeatureTileMeasurements3D as f}from"./FeatureTileMeasurements3D.js";import{maxLODLevelDelta as g}from"./FeatureTileVisibility3D.js";import{toBoundingRect as T}from"../../support/extentUtils.js";import{TaskPriority as v,noBudget as y}from"../../../support/Scheduler.js";const E=60;let w=class extends t{constructor(e){super(e),this.tiles=new s,this.tileSize=512,this._idToTile=new Map,this._dirty=u(!1),this._pendingTiles=u(null),this._newTiles=new n,this._measurements=new f(e.renderCoordsHelper,e.terrain.tilingScheme,this._opaqueGround)}initialize(){this.addHandles([l(()=>this.tileSize,()=>this._reset(),o),l(()=>[this.pointsOfInterest.cameraOnSurface?.location,this.viewState?.contentCamera,this.pointsOfInterest.focus?.location,this.terrain?.baseOpacity??1],()=>this._setDirty(),o),l(()=>this.tilingScheme,e=>{this._reset(),this._measurements=new f(this.renderCoordsHelper,e,this._opaqueGround)},a),l(()=>this._opaqueGround,e=>this._measurements.opaqueGround=e,a)]),this._frameWorker=this.scheduler?.registerTask(v.FEATURE_TILE_TREE,this)}destroy(){this._frameWorker=r(this._frameWorker),this._measurements=null,this._newTiles.prune()}get tilingScheme(){return this.terrain.tilingScheme?.clone()}set filterExtent(e){if(null!=e&&!e.spatialReference.equals(this.viewState.spatialReference))return void i.getLogger(this).error("#extent","extent spatial reference needs to be in the same spatial reference as the view");const t=this._get("filterExtent");if(t===e||null!=t&&e&&t.equals(e))return;const s=null!=e?e.clone():null;this._set("filterExtent",s),this._setDirty()}get _filterExtentRect(){if(null==this.filterExtent)return null;const e=m();return T(this.filterExtent,e,this.tilingScheme.spatialReference),e}get _rootTileIds(){const{tilingScheme:e}=this;return this._filterExtentRect&&e?e.rootTilesInExtent(this._filterExtentRect):[[0,0,0]]}set suspended(e){e!==this._get("suspended")&&(this._set("suspended",e),this._setDirty())}get updating(){return this._dirty.value||!!this._pendingTiles.value}get _opaqueGround(){return 1===(this.terrain?.baseOpacity??1)}_setDirty(){this.suspended||(this._frameWorker?this._dirty.value=!0:this.runTask(y))}_clear(){this.tiles.removeAll(),this._idToTile.clear(),this._reset(!1),this._dirty.value=!1}get readyToRun(){return this.updating}_reset(e=!0){this._newTiles.clear(),this._pendingTiles.value=null,e&&this._setDirty()}_getRootTiles(){const e=this.tilingScheme;return this._rootTileIds.map(t=>new c(t[0],t[1],t[2],e))}runTask(e){e="test"===process.env.NODE_ENV?y:e,this._dirty.value=!1,this._pendingTiles.value||(this._startUpdate(e),null!=this._frameWorker&&(this._frameWorker.priority=v.FEATURE_TILE_TREE_ACTIVE)),this._splitPendingTiles(e),this._pendingTiles.value||null==this._frameWorker||(this._frameWorker.priority=v.FEATURE_TILE_TREE)}_startUpdate(e){if(this.suspended)return;if(!this.tilingScheme)return void this._clear();const{_measurements:t,_filterExtentRect:s,_newTiles:i}=this;t.setup(this.viewState.contentCamera,this.pointsOfInterest.focus.location,this.pointsOfInterest.cameraOnSurface.location.z??0),this._pendingTiles.value=this._getRootTiles().filter(e=>{if(t.update(e),e.measures.visible&&(!s||!e.extent||p(e.extent,s))){if(e.measures.splitPriority>0)return!0;i.push(e)}return!1}).sort(x),this._newTiles.clear(),e.madeProgress()}_splitPendingTiles(e){const t=this._pendingTiles.value;if(!t)return;const{tilingScheme:s,_filterExtentRect:i,_newTiles:r,_measurements:n}=this;for(;t.length>0&&this._tileBudgetRatio<=2;){const l=t.pop();if(e.madeProgress(),l.measures.splitPriority>0){s.ensureMaxLod(l.level+1);const e=l.createChildren();for(const s of e)n.update(s),!s.measures.visible||i&&s.extent&&!p(s.extent,i)||(s.measures.splitPriority>0?t.push(s):r.push(s));t.sort(x),this._mergeNewTiles(2),this._mergeNewTiles(2,!0)}else r.push(l);if(e.done)return}r.pushArray(t),this._pendingTiles.value=null,this._updateTiles(),r.clear(),n.done()}get _tileBudgetRatio(){return(this._newTiles.length+(this._pendingTiles.value?.length??0))/E}_mergeNewTiles(e,t=!1){if(this._tileBudgetRatio<=e)return;const{_newTiles:s,_measurements:i}=this;s.sort((e,t)=>t.measures.distance-e.measures.distance);const r=new Map(s.map(e=>[e.id,e])),n=s.length;for(const l of r.values()){const{lij:n,measures:o}=l;if(!o.mergeable||n[1]%2!=0||n[2]%2!=0||n[0]<=1||l.lodLevelDelta>=g)continue;const a=o.lodLevel;let u=a,h=!0;const d=r.get(_(n[0],n[1]+1,n[2]));let m=Math.abs((d?.measures.lodLevel??0)-a),p=0===m||t&&d?.measures.mergeable&&m<=1;if(!d||!p)continue;u+=d.measures.lodLevel,h&&=0===m;const f=r.get(_(n[0],n[1],n[2]+1));if(m=Math.abs((f?.measures.lodLevel??0)-a),p=0===m||t&&f?.measures.mergeable&&m<=1,!f||!p)continue;u+=f.measures.lodLevel,h&&=0===m;const T=r.get(_(n[0],n[1]+1,n[2]+1));if(m=Math.abs((T?.measures.lodLevel??0)-a),p=0===m||t&&T?.measures.mergeable&&m<=1,!T||!p)continue;u+=T.measures.lodLevel,h&&=0===m,s.removeUnordered(l),s.removeUnordered(d),s.removeUnordered(f),s.removeUnordered(T),r.delete(l.id),r.delete(d.id),r.delete(f.id),r.delete(T.id);const v=new c(n[0]-1,n[1]/2,n[2]/2,this.tilingScheme);if(i.update(v),v.measures.visible=!0,v.measures.lodLevel=u/4,v.measures.mergeable=h,s.push(v),r.set(v.id,v),this._tileBudgetRatio<=e)return}s.length<n&&this._mergeNewTiles(e,t)}_updateTiles(){this._mergeNewTiles(1),this._mergeNewTiles(1,!0);for(const i of this.tiles.items)i.used=!1;let e=!1;const t=this._newTiles.filter(t=>{const s=this._idToTile.get(t.id);return s?(e||=s.measures.lodLevel!==t.measures.lodLevel,s.measures={...t.measures},s.used=!0):this._idToTile.set(t.id,t),!s}),s=this.tiles.items.filter(e=>!e.used&&(this._idToTile.delete(e.id),!0));this.tiles.removeMany(s),this.tiles.addMany(t),this._sortTiles(),!e||s.length||t.length||this.tiles.emit("change")}_sortTiles(){this.viewState.fixedContentCamera||this.tiles.sort((e,t)=>e.measures.distance-t.measures.distance),this.tiles.forEach((e,t)=>e.loadPriority=t)}};function x(e,t){return e.lodLevelDelta-t.lodLevelDelta||e.measures.splitPriority-t.measures.splitPriority||t.measures.distance-e.measures.distance}e([h({constructOnly:!0})],w.prototype,"scheduler",void 0),e([h({constructOnly:!0})],w.prototype,"renderCoordsHelper",void 0),e([h({constructOnly:!0})],w.prototype,"pointsOfInterest",void 0),e([h({constructOnly:!0})],w.prototype,"viewState",void 0),e([h({constructOnly:!0})],w.prototype,"terrain",void 0),e([h()],w.prototype,"tiles",void 0),e([h()],w.prototype,"tileSize",void 0),e([h({readOnly:!0})],w.prototype,"tilingScheme",null),e([h()],w.prototype,"filterExtent",null),e([h({readOnly:!0})],w.prototype,"_filterExtentRect",null),e([h({readOnly:!0})],w.prototype,"_rootTileIds",null),e([h({value:!1})],w.prototype,"suspended",null),e([h({readOnly:!0})],w.prototype,"updating",null),w=e([d("esri.views.3d.layers.support.FeatureTileTree3D")],w);export{w as FeatureTileTree3D};