@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 7.03 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.33/esri/copyright.txt for details.
*/
import{_ as e}from"../../../chunks/tslib.es6.js";import{forEach as t,result as r}from"../../../core/asyncUtils.js";import{makeHandle as i}from"../../../core/handleUtils.js";import a from"../../../core/Logger.js";import{abortMaybe as s}from"../../../core/maybe.js";import{isAbortError as o,onAbort as n,throwIfAborted as l,isAborted as h,createAbortError as m}from"../../../core/promiseUtils.js";import{whenOnce as g}from"../../../core/reactiveUtils.js";import{property as d}from"../../../core/accessorSupport/decorators/property.js";import"../../../core/has.js";import"../../../core/RandomLCG.js";import{subclass as c}from"../../../core/accessorSupport/decorators/subclass.js";import u from"../../../geometry/Extent.js";import{create as p,equals as f,width as y,height as x,copy as w,intersection as _}from"../../../geometry/support/aaBoundingRect.js";import{DrapeSourceType as b}from"./interfaces.js";import R from"./SubView3D.js";import{computeImageExportSize as E,createGeometryForExtent as v,createOuterImageGeometry as j}from"./support/overlayImageUtils.js";import{debugFlags as S}from"../support/debugFlags.js";import{OverlayIndex as A}from"../terrain/interfaces.js";import{DirtyOperation as I}from"../webgl-engine/lib/ModelDirtyTypes.js";import{RenderGeometry as M}from"../webgl-engine/lib/RenderGeometry.js";import{Texture as T}from"../webgl-engine/lib/Texture.js";import{UpdatePolicy as D}from"../webgl-engine/lib/UpdatePolicy.js";import{ImageMaterial as G}from"../webgl-engine/materials/ImageMaterial.js";import{TextureWrapMode as P}from"../../webgl/enums.js";let C=class extends R{constructor(e){super(e),this.drapeSourceType=b.RasterImage,this.updatePolicy=D.SYNC,this.type="draped",this.maximumDataResolution=null,this._images=new Array,this._extents=new Array,this._overlays=new Array,this._drapeSourceRenderer=null}initialize(){this._drapeSourceRenderer=this.view.basemapTerrain.overlayManager.registerGeometryDrapeSource(this),this.addHandles(i((()=>this.view.basemapTerrain.overlayManager.unregisterDrapeSource(this))))}setDrapingExtent(e,t){this._spatialReference=t,e.forEach(((e,t)=>{this._overlays[t]=e,this._updateImageExtent(e,t)}))}destroy(){this.clear()}get spatialReference(){return this._spatialReference}_updateImageExtent(e,t){const r=this._clippedExtent(e.extent,O);if(null==r)return;const i=E(e.extent,r,e.resolution);let s=e.pixelRatio*this.view.state.pixelRatio;const{layer:n}=this;if("imageMaxWidth"in n&&null!=n.imageMaxWidth||"imageMaxHeight"in n&&null!=n.imageMaxHeight){const e=n.imageMaxWidth,t=n.imageMaxHeight;if(i.width>e){const t=e/i.width;i.height=Math.floor(i.height*t),i.width=e,s*=t}if(i.height>t){const e=t/i.height;i.width=Math.floor(i.width*e),i.height=t,s*=e}}const l=this._extents[t];l&&f(l.extent,r)&&this._imageSizeEquals(r,l.imageSize,i)||(this._extents[t]={extent:p(r),imageSize:i,pixelRatio:s},this.suspended||this._fetch(t).catch((e=>{o(e)||a.getLogger(this).error(e)})))}clear(){for(let e=0;e<this._images.length;e++)this._clearImage(e)}async doRefresh(e){const t=[];for(let r=0;r<this._extents.length;r++)this._extents[r]&&t.push(this._fetch(r,e));await Promise.allSettled(t)}async processResult(e,t,r){(t instanceof HTMLImageElement||t instanceof HTMLCanvasElement)&&(e.image=t)}findExtentInfoAt(e){for(const t of this._extents){const r=t.extent;if(new u(r[0],r[1],r[2],r[3],this._spatialReference).contains(e))return t}return null}async redraw(e,r){await t(this._images,(async(t,i)=>{t&&(await e(t,r),await this._createStageObjects(i,t.image,r))}))}_imageSizeEquals(e,t,r){if(!this.maximumDataResolution)return!1;const i=y(e)/this.maximumDataResolution.x,a=x(e)/this.maximumDataResolution.y,s=i/t.width,o=a/t.height,n=i/r.width,l=a/r.height,h=Math.abs(s-n),m=Math.abs(o-l),g=S.TESTS_DISABLE_OPTIMIZATIONS?0:1.5;return h<=g&&m<=g}async _fetch(e,t){if(this.suspended)return;const r=this._extents[e],i=r.extent;this._images[e]||(this._images[e]={texture:null,material:null,renderGeometry:null,loadingPromise:null,loadingAbortController:null,image:null,pixelData:null,renderExtent:p(i)});const g=this._images[e];g.loadingAbortController=s(g.loadingAbortController);const d=new u(i[0],i[1],i[2],i[3],this._spatialReference);if(0===d.width||0===d.height)return void this._clearImage(e);const c=new AbortController;g.loadingAbortController=c,n(t,(()=>c.abort()));const f=c.signal,y=this._waitFetchReady(f).then((async()=>{l(f);const t={requestAsImageElement:!0,pixelRatio:this._overlays[e].pixelRatio,...this.layerView.getFetchOptions(),signal:f},{height:i,width:a}=r.imageSize;return this.layer?"imagery"===this.layer.type?this.layer.internalFetchImage(d,a,i,t):this.layer.fetchImage(d,a,i,t):null})).then((e=>{if(h(f))throw a.getLogger(this).warnOnce("A call to fetchImage resolved even though the request was aborted. fetchImage should not resolve if options.signal.aborted is true."),m();return this.processResult(g,e)})).then((()=>{w(g.renderExtent,i)}));g.loadingPromise=y,await this.updatingHandles.addPromise(y.then((async()=>{l(f),await this._createStageObjects(e,g.image,f)})).catch((e=>{throw e&&!o(e)&&a.getLogger(this).error(e),e})).finally((()=>{y===g.loadingPromise&&(g.loadingPromise=null,g.loadingAbortController=null)})))}_clearImage(e){const t=this._images[e];if(t){null!=t.renderGeometry&&(this._drapeSourceRenderer.removeGeometries([t.renderGeometry],I.UPDATE),t.renderGeometry=null);const e=this.view.stage,r=t.texture;r?.unload(),e.removeTexture(r),t.texture=null,t.material=null,t.loadingAbortController=s(t.loadingAbortController),t.loadingPromise=null,t.image=null,t.pixelData=null}}async _createStageObjects(e,t,i){const a=this.view.stage,s=this._images[e],o=()=>{s.texture?.unload(),a.removeTexture(s.texture),s.texture=null,s.renderGeometry&&(this._drapeSourceRenderer.removeGeometries([s.renderGeometry],I.UPDATE),s.renderGeometry=null)};if(t){const n=new T(t,{width:t.width,height:t.height,preMultiplyAlpha:!0,wrap:{s:P.CLAMP_TO_EDGE,t:P.CLAMP_TO_EDGE}});if(await r(this._images[e===A.INNER?A.OUTER:A.INNER].loadingPromise),l(i),o(),await a.schedule((()=>n.load(a.renderView.renderingContext)),i),!n.loaded)return void o();let h;if(a.addTexture(n),s.texture=n,s.material??=new G({draped:!0,texture:n}),s.material.setParameters({texture:n}),e===A.INNER)h=v(s.material,s.renderExtent);else{const e=this._images[0].renderExtent;if(!e)return void o();h=j(s.material,e,s.renderExtent)}s.renderGeometry=new M(h),s.renderGeometry.localOrigin=this._overlays[e].renderLocalOrigin,this._drapeSourceRenderer.addGeometries([s.renderGeometry],I.UPDATE)}else o(),s.material=null}_clippedExtent(e,t){if("local"!==this.view.viewingMode)return w(t,e);const r=this.view.basemapTerrain;return r.ready?_(e,r.extent,t):w(t,e)}async _waitFetchReady(e){await g((()=>this.view.stationary),e),l(e)}};e([d()],C.prototype,"type",void 0),C=e([c("esri.views.3d.layers.DrapedSubView3D")],C);const O=p();export{C as default};