UNPKG

@arcgis/core

Version:

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

6 lines (5 loc) 8.17 kB
/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.32/esri/copyright.txt for details. */ import{_ as e}from"../../../../chunks/tslib.es6.js";import t from"../../../../core/Accessor.js";import s from"../../../../core/Collection.js";import{makeHandle as i}from"../../../../core/handleUtils.js";import"../../../../core/has.js";import r from"../../../../core/Logger.js";import{removeMaybe as l}from"../../../../core/maybe.js";import o from"../../../../core/PooledArray.js";import{watch as n,syncAndInitial as a,sync as u}from"../../../../core/reactiveUtils.js";import{signal as h}from"../../../../core/signal.js";import{generateUID as d}from"../../../../core/uid.js";import{property as c}from"../../../../core/accessorSupport/decorators/property.js";import"../../../../core/RandomLCG.js";import{subclass as m}from"../../../../core/accessorSupport/decorators/subclass.js";import{create as p,intersects as _}from"../../../../geometry/support/aaBoundingRect.js";import{FeatureTileDescriptor as f,getFeatureTileId as g}from"./FeatureTileDescriptor.js";import{FeatureTileMeasurements3D as T}from"./FeatureTileMeasurements3D.js";import{maxLODLevelDelta as v}from"./FeatureTileVisibility3D.js";import{toBoundingRect as y}from"../../support/extentUtils.js";import{TaskPriority as E,noBudget as w}from"../../../support/Scheduler.js";const S=60;let x=class extends t{constructor(e){super(e),this.tiles=new s,this.tileSize=512,this._idToTile=new Map,this._clients=new Set,this._dirty=h(!1),this._pendingTiles=h(null),this._newTiles=new o,this._tests=!1,this._measurements=new T(e.renderCoordsHelper,e.tilingSchemeOwner.tilingScheme,this._opaqueGround)}initialize(){const e=()=>this._setDirty(),t=()=>this._reset();this.addHandles([n((()=>this.tileSize),t,a),n((()=>this.cameraOnSurface?.location),e,a),n((()=>this.viewState?.contentCamera),e,a),n((()=>this.focus?.location),e,a),n((()=>this.terrain?.baseOpacity??1),e),n((()=>this.tilingScheme),(e=>{this._reset(),this._measurements=new T(this.renderCoordsHelper,e,this._opaqueGround)}),u),n((()=>this._opaqueGround),(e=>this._measurements.opaqueGround=e),u)]),this._frameWorker=this.scheduler?.registerTask(E.FEATURE_TILE_TREE,this)}destroy(){this._frameWorker=l(this._frameWorker)}get tilingScheme(){const e=this.tilingSchemeOwner.tilingScheme;if(!e)return null;return e.clone()}set filterExtent(e){if(null!=e&&!e.spatialReference.equals(this.viewState.spatialReference))return void r.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=p();return y(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}addClient(){const e=d();return this._clients.add(e),1===this._clients.size&&this._setDirty(),i((()=>this._removeClient(e)))}_removeClient(e){this._clients.delete(e),this._hasClients||this._clear()}get _hasClients(){return this._clients.size>0}get _opaqueGround(){return 1===(this.terrain?.baseOpacity??1)}_setDirty(){this._hasClients&&!this.suspended&&(this._frameWorker?this._dirty.value=!0:this.runTask(w))}_clear(){this.tiles.removeAll(),this._idToTile.clear(),this._reset(),this._dirty.value=!1}get running(){return this.updating}_reset(){this._newTiles.clear(),this._pendingTiles.value=null,this._setDirty()}_getRootTiles(){const e=this.tilingScheme;return this._rootTileIds.map((t=>new f(t[0],t[1],t[2],e)))}runTask(e){e=this._tests?w:e,this._dirty.value=!1,this._pendingTiles.value||(this._startUpdate(e),null!=this._frameWorker&&(this._frameWorker.priority=E.FEATURE_TILE_TREE_ACTIVE)),this._splitPendingTiles(e),this._pendingTiles.value||null==this._frameWorker||(this._frameWorker.priority=E.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.focus.location,this.cameraOnSurface.location.z??0),this._pendingTiles.value=this._getRootTiles().filter((e=>{if(t.update(e),e.measures.visible&&(!s||_(e.extent,s))){if(e.measures.splitPriority>0)return!0;i.push(e)}return!1})).sort(j),this._newTiles.clear(),e.madeProgress()}_splitPendingTiles(e){const t=this._pendingTiles.value;if(!t)return;const{tilingScheme:s,_filterExtentRect:i,_newTiles:r,_measurements:l}=this;for(;t.length>0&&this._tileBudgetExceeded<1;){const o=t.pop();if(e.madeProgress(),o.measures.splitPriority>0){s.ensureMaxLod(o.level+1);const e=o.createChildren();for(const s of e)l.update(s),!s.measures.visible||i&&!_(s.extent,i)||(s.measures.splitPriority>0?t.push(s):r.push(s));t.sort(j),this._tileBudgetExceeded>=1&&(this._mergeNewTiles(),this._tileBudgetExceeded>=1&&this._mergeNewTiles(!0))}else r.push(o);if(e.done)return}r.pushArray(t),this._pendingTiles.value=null,this._updateTiles(),r.clear(),l.done()}get _tileBudgetExceeded(){return Math.max(0,(this._newTiles.length+(this._pendingTiles.value?.length??0))/S-1)}_mergeNewTiles(e=!1){const{_newTiles:t,_measurements:s}=this,i=new Map(t.map((e=>[e.id,e])));let r=!1;return i.forEach((l=>{const{lij:o,measures:n}=l;if(!n.mergeable||o[1]%2!=0||o[2]%2!=0||o[0]<=1||l.lodLevelDelta>=v)return;const a=n.lodLevel;let u=a,h=!0;const d=i.get(g(o[0],o[1]+1,o[2]));let c=Math.abs((d?.measures.lodLevel??0)-a),m=0===c||e&&d?.measures.mergeable&&c<=1;if(!d||!m)return;u+=d.measures.lodLevel,h&&=0===c;const p=i.get(g(o[0],o[1],o[2]+1));if(c=Math.abs((p?.measures.lodLevel??0)-a),m=0===c||e&&p?.measures.mergeable&&c<=1,!p||!m)return;u+=p.measures.lodLevel,h&&=0===c;const _=i.get(g(o[0],o[1]+1,o[2]+1));if(c=Math.abs((_?.measures.lodLevel??0)-a),m=0===c||e&&_?.measures.mergeable&&c<=1,!_||!m)return;u+=_.measures.lodLevel,h&&=0===c,t.removeUnordered(l),t.removeUnordered(d),t.removeUnordered(p),t.removeUnordered(_);const T=new f(o[0]-1,o[1]/2,o[2]/2,this.tilingScheme);s.update(T),T.measures.visible=!0,T.measures.lodLevel=u/4,T.measures.mergeable=h,t.push(T),r=!0})),r}_updateTiles(){for(;this._mergeNewTiles(););for(;this._tileBudgetExceeded&&this._mergeNewTiles(!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 j(e,t){return e.lodLevelDelta-t.lodLevelDelta||e.measures.splitPriority-t.measures.splitPriority||t.measures.distance-e.measures.distance}e([c({constructOnly:!0})],x.prototype,"scheduler",void 0),e([c({constructOnly:!0})],x.prototype,"renderCoordsHelper",void 0),e([c({constructOnly:!0})],x.prototype,"tilingSchemeOwner",void 0),e([c({constructOnly:!0})],x.prototype,"cameraOnSurface",void 0),e([c({constructOnly:!0})],x.prototype,"focus",void 0),e([c({constructOnly:!0})],x.prototype,"viewState",void 0),e([c({constructOnly:!0})],x.prototype,"terrain",void 0),e([c()],x.prototype,"tiles",void 0),e([c()],x.prototype,"tileSize",void 0),e([c({readOnly:!0})],x.prototype,"tilingScheme",null),e([c()],x.prototype,"filterExtent",null),e([c({readOnly:!0})],x.prototype,"_filterExtentRect",null),e([c({readOnly:!0})],x.prototype,"_rootTileIds",null),e([c({value:!1})],x.prototype,"suspended",null),e([c({readOnly:!0})],x.prototype,"updating",null),x=e([m("esri.views.3d.layers.support.FeatureTileTree3D")],x);export{x as FeatureTileTree3D};