@doegis/core
Version:
DOE GIS API
3 lines (1 loc) • 5.09 kB
JavaScript
import"../../../../../core/has.js";import t from"../../../../../core/Logger.js";import{isSome as e,unwrapOrThrow as s,isNone as r}from"../../../../../core/maybe.js";import{throwIfAborted as o,after as a}from"../../../../../core/promiseUtils.js";import n from"../../../../../core/RandomLCG.js";import{BaseFeatureSource as i}from"./BaseFeatureSource.js";import{FeatureSetReaderIndirect as d}from"../support/FeatureSetReaderPBFIndirect.js";import{UpdateToken as u}from"../support/UpdateToken.js";function h(t,e,s){const r=t.getXHydrated(),o=t.getYHydrated(),a=e.getColumnForX(r),n=Math.floor(e.normalizeCol(a));return`${s}/${Math.floor(e.getRowForY(o))}/${n}`}function l(t,e){if(r(t))return null;const s=e.transform,o=t.getQuantizationTransform();if(r(o)){const[e,r]=s.scale,[o,a]=s.translate,n=-o/e,i=1/e,d=a/r,u=1/-r;return t.transform(n,d,i,u)}const[a,n]=o.scale,[i,d]=o.translate,[u,h]=s.scale,[l,c]=s.translate,g=a/u,_=(i-l)/u,p=n/h,f=(-d+c)/h;return t.transform(_,f,g,p)}class c extends i{constructor(t){super(t),this.mode="snapshot",this._loading=!0,this._controller=new AbortController,this._downloadPromise=null,this._didSendEnd=!1,this._queries=new Array,this._invalidated=!1,this._hasAggregates=!1,this._random=new n(1e3),this._store=t.store,this._markedIdsBufId=this._store.storage.createBitset()}destroy(){super.destroy(),this._controller.abort()}get loading(){return this._loading}get _signal(){return this._controller.signal}update(t,s){super.update(t,s),null==this._featureCount&&(this._featureCount=s.initialFeatureCount),e(s.changedFeatureCount)&&(this._featureCount=s.changedFeatureCount),this._hasAggregates=!!t.targets?.aggregate}async resend(t=!1){if(await this._downloadPromise,this._invalidated||t){const t=s(this._featureCount,"Expected featureCount to be defined");return this._invalidated=!1,this._subscriptions.forEach((t=>t.clear())),this._downloadPromise=this._download(t),void await this._downloadPromise}const e=this._queries.map((({query:t,reader:e})=>this._sendPatchQuery(t,e)));await Promise.all(e),this._subscriptions.forEach((t=>{t.requests.done.forEach((t=>this._onMessage(t.message)))}))}async refresh(t,e){e&&(this._featureCount=e.featureCount),await this.resend(!0)}async _sendPatchQuery(t,s){const r=e(t.outFields)?t.outFields:[],a=this._queryInfo.outFields,n=a.filter((t=>!r.includes(t)));if(!n.length)return;const i=t.clone(),d=this._signal;i.returnGeometry=!1,i.returnCentroid=!1,i.outFields=n,t.outFields=a;const u=await this._queue.push({query:i,depth:0,signal:d});o({signal:d}),s.joinAttributes(u)}async _fetchDataTile(t){if(!this._downloadPromise){const t=s(this._featureCount,"Expected featureCount to be defined");this._downloadPromise=this._download(t)}const e=this._store.search(t),r=this._subscriptions.get(t.key.id),o=e.length-1;for(let s=0;s<o;s++){const o=l(e[s],t),n={type:"append",id:t.id,addOrUpdate:o,end:!1,status:u.empty()};r.add({query:null,message:n}),this._hasAggregates||await a(1),this._onMessage(n)}const n=l(o>=0?e[o]:null,t),i=this._didSendEnd,d={type:"append",id:t.id,addOrUpdate:n,end:i,status:u.empty()};r.add({query:null,message:d}),this._onMessage(d)}async _download(e){try{await this.whenInitialized();const t=this._store.storage.getBitset(this._markedIdsBufId),s=new Set;t.clear();const r=Math.ceil(e/this.pageSize),o=Array.from({length:r},((t,e)=>e)).sort(((t,e)=>this._random.getInt()-this._random.getInt())).map((e=>this._downloadPage(e,t,s)));await Promise.all(o),this._store.sweepFeatures(t,this._store.storage),this._store.sweepFeatureSets(s)}catch(s){t.getLogger("esri.views.2d.layers.features.sources.SnapshotFeatureSource").error("mapview-snapshot-source","Encountered and error when downloading feature snapshot",s)}this._sendEnd(),this._loading=!1}async _downloadPage(t,s,r){const a=this.pageSize,n={start:t*a,num:a,cacheHint:!0};e(this.maxRecordCountFactor)&&(n.maxRecordCountFactor=this.maxRecordCountFactor);const i=this.createQuery(n),d=this._signal,u=await this._queue.push({query:i,depth:t,signal:d});o({signal:d}),this._queries.push({query:i,reader:u}),this._store.insert(u),r.add(u.instance);const h=u.getCursor();for(;h.next();)s.set(h.getDisplayId());this._send(u)}_send(t){if(!this._subscriptions.size)return;let s=null;const o=new Map,a=new Set,n=new Map;this._subscriptions.forEach((t=>{const e=t.tile;o.set(e.key.id,null),s=e.tileInfoView,a.add(e.level);const{row:r,col:i}=e.key,d=`${e.level}/${r}/${i}`,u=n.get(d)??[];u.push(t),n.set(d,u)}));for(const e of a){const a=s.getLODInfoAt(e),i=t.getCursor();for(;i.next();){const t=h(i,a,e),s=i.getIndex();if(n.has(t))for(const e of n.get(t)){const t=e.tile.id;let a=o.get(t);r(a)&&(a=[],o.set(t,a)),a.push(s)}}}o.forEach(((s,r)=>{if(e(s)){const e=this._subscriptions.get(r),o={type:"append",id:r,addOrUpdate:l(d.from(t,s),e.tile),end:!1,status:u.empty()};e.add({query:null,message:o}),this._onMessage(o)}}))}_sendEnd(){this._subscriptions.forEach((t=>{const e={type:"append",id:t.tile.id,addOrUpdate:null,end:!0,status:u.empty()};t.add({query:null,message:e}),this._onMessage(e)})),this._didSendEnd=!0}}export{c as SnapshotFeatureSource};