UNPKG

@arcgis/core

Version:

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

6 lines (5 loc) 4.42 kB
/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.32/esri/copyright.txt for details. */ import t from"../../request.js";import e from"../../geometry/Point.js";import{project as r}from"../../geometry/projection.js";import{projectResolution as i,getProjectionOffsetGrid as a}from"../../layers/support/rasterFunctions/rasterProjectionHelper.js";import{isImageSource as s,rasterize as n}from"../2d/engine/Bitmap.js";import o from"../2d/engine/webgl/VertexStream.js";import{createProgramTemplate as m}from"../2d/engine/webgl/shaders/MaterialPrograms.js";import{TextureWrapMode as c,PixelFormat as p,PixelType as h,ColorAttachment as x}from"../webgl/enums.js";import{FramebufferObject as u}from"../webgl/FramebufferObject.js";import{createTransformTexture as d}from"../webgl/rasterUtils.js";import{RenderingContext as _}from"../webgl/RenderingContext.js";import{Texture as g}from"../webgl/Texture.js";import{TextureDescriptor as f}from"../webgl/TextureDescriptor.js";class l{constructor(t){if(this._ownsRctx=!1,t)this._ownsRctx=!1,this._rctx=t;else{if(l._instance)return l._instanceRefCount++,l._instance;l._instanceRefCount=1,l._instance=this,this._ownsRctx=!0;const t=document.createElement("canvas").getContext("webgl2");t.getExtension("OES_texture_float"),this._rctx=new _(t,{})}const e={applyProjection:!0,bilinear:!1,bicubic:!1},r=m("raster/reproject","raster/reproject",new Map([["a_position",0]]),e);this._program=this._rctx.programCache.acquire(r.shaders.vertexShader,r.shaders.fragmentShader,r.attributes),this._rctx.useProgram(this._program),this._program.setUniform1f("u_opacity",1),this._program.setUniform1i("u_image",0),this._program.setUniform1i("u_flipY",0),this._program.setUniform1i("u_transformGrid",1),this._quad=new o(this._rctx,[0,0,1,0,0,1,1,1])}reprojectTexture(t,s,n=!1){const o=r(t.extent,s),m=new e({x:(t.extent.xmax-t.extent.xmin)/t.texture.descriptor.width,y:(t.extent.ymax-t.extent.ymin)/t.texture.descriptor.height,spatialReference:t.extent.spatialReference}),{x:_,y:g}=i(m,s,t.extent);let l=(_+g)/2;const w=Math.round((o.xmax-o.xmin)/l),b=Math.round((o.ymax-o.ymin)/l);l=(o.width/w+o.height/b)/2;const j=new e({x:l,y:l,spatialReference:o.spatialReference}),D=a({projectedExtent:o,srcBufferExtent:t.extent,pixelSize:j,hasWrapAround:!0,spacing:[16,16]}),R=d(this._rctx,D),C=new f(w,b);C.wrapMode=c.CLAMP_TO_EDGE;const T=new u(this._rctx,C);this._rctx.bindFramebuffer(T),this._rctx.setViewport(0,0,w,b),this._rctx.useProgram(this._program),this._rctx.bindTexture(t.texture,0),this._rctx.bindTexture(R,1),this._quad.bind();const{width:y=0,height:E=0}=t.texture.descriptor;if(this._program.setUniform2f("u_srcImageSize",y,E),this._program.setUniform2fv("u_transformSpacing",D.spacing),this._program.setUniform2fv("u_transformGridSize",D.size),this._program.setUniform2f("u_targetImageSize",w,b),this._quad.draw(),this._quad.unbind(),this._rctx.useProgram(null),this._rctx.bindFramebuffer(null),R.dispose(),n){const{width:t,height:e}=T,r=new ImageData(t??0,e??0);T.readPixels(0,0,t??0,e??0,p.RGBA,h.UNSIGNED_BYTE,r.data);const i=T.detachColorTexture(x.COLOR_ATTACHMENT0);return T.dispose(),{texture:i,extent:o,imageData:r}}const M=T.detachColorTexture(x.COLOR_ATTACHMENT0);return T.dispose(),{texture:M,extent:o}}reprojectBitmapData(t,e){const r=s(t.bitmapData)?n(t.bitmapData):t.bitmapData,i=new f;i.wrapMode=c.CLAMP_TO_EDGE,i.width=t.bitmapData.width,i.height=t.bitmapData.height;const a=new g(this._rctx,i,r),o=this.reprojectTexture({texture:a,extent:t.extent},e,!0);o.texture.dispose();const m=document.createElement("canvas"),p=o.imageData;m.width=p.width,m.height=p.height;return m.getContext("2d").putImageData(p,0,0),{bitmapData:m,extent:o.extent}}async loadAndReprojectBitmapData(e,r,i){const a=(await t(e,{responseType:"image"})).data,s=document.createElement("canvas");s.width=a.width,s.height=a.height;const n=s.getContext("2d");n.drawImage(a,0,0);const o=n.getImageData(0,0,s.width,s.height);if(r.spatialReference.equals(i))return{bitmapData:o,extent:r};const m=this.reprojectBitmapData({bitmapData:o,extent:r},i);return{bitmapData:m.bitmapData,extent:m.extent}}destroy(){this._ownsRctx?(l._instanceRefCount--,0===l._instanceRefCount&&(this._quad.dispose(),this._program.dispose(),this._rctx.dispose(),l._instance=null)):(this._quad.dispose(),this._program.dispose())}}l._instanceRefCount=0;export{l as ImageReprojector};