UNPKG

@doegis/core

Version:

DOE GIS API

3 lines (1 loc) 4.48 kB
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{PixelFormat as p,PixelType as h,TextureWrapMode as c,TextureSamplingMode as x,TargetType as d,DepthStencilTargetType as g,ColorAttachment as u}from"../webgl/enums.js";import{FramebufferObject as _}from"../webgl/FramebufferObject.js";import{createTransformTexture as f}from"../webgl/rasterUtils.js";import{RenderingContext as l}from"../webgl/RenderingContext.js";import{Texture as w}from"../webgl/Texture.js";class b{constructor(t){if(this._ownsRctx=!1,t)this._ownsRctx=!1,this._rctx=t;else{if(b._instance)return b._instanceRefCount++,b._instance;b._instanceRefCount=1,b._instance=this,this._ownsRctx=!0;const t=document.createElement("canvas").getContext("webgl");t.getExtension("OES_texture_float"),this._rctx=new l(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:l,y:b}=i(m,s,t.extent);let T=(l+b)/2;const R=Math.round((o.xmax-o.xmin)/T),j=Math.round((o.ymax-o.ymin)/T);T=(o.width/R+o.height/j)/2;const E=new e({x:T,y:T,spatialReference:o.spatialReference}),D=a({projectedExtent:o,srcBufferExtent:t.extent,pixelSize:E,hasWrapAround:!0,spacing:[16,16]}),C=f(this._rctx,D),y=new w(this._rctx,{width:R,height:j,pixelFormat:p.RGBA,dataType:h.UNSIGNED_BYTE,wrapMode:c.CLAMP_TO_EDGE,samplingMode:x.LINEAR,hasMipmap:!1}),M=new _(this._rctx,{colorTarget:d.TEXTURE,depthStencilTarget:g.NONE,width:R,height:j},y);this._rctx.bindFramebuffer(M),this._rctx.setViewport(0,0,R,j),this._rctx.useProgram(this._program),this._rctx.bindTexture(t.texture,0),this._rctx.bindTexture(C,1),this._quad.bind();const{width:A=0,height:S=0}=t.texture.descriptor;if(this._program.setUniform2f("u_srcImageSize",A,S),this._program.setUniform2fv("u_transformSpacing",D.spacing),this._program.setUniform2fv("u_transformGridSize",D.size),this._program.setUniform2f("u_targetImageSize",R,j),this._quad.draw(),this._quad.unbind(),this._rctx.useProgram(null),this._rctx.bindFramebuffer(null),C.dispose(),n){const{width:t=0,height:e=0}=M.descriptor,r=new ImageData(t,e);return M.readPixels(0,0,t,e,p.RGBA,h.UNSIGNED_BYTE,r.data),M.detachColorTexture(u.COLOR_ATTACHMENT0),M.dispose(),{texture:y,extent:o,imageData:r}}return M.detachColorTexture(u.COLOR_ATTACHMENT0),M.dispose(),{texture:y,extent:o}}reprojectBitmapData(t,e){const r=s(t.bitmapData)?n(t.bitmapData):t.bitmapData,i=new w(this._rctx,{width:t.bitmapData.width,height:t.bitmapData.height,pixelFormat:p.RGBA,dataType:h.UNSIGNED_BYTE,wrapMode:c.CLAMP_TO_EDGE,samplingMode:x.LINEAR,hasMipmap:!1},r),a=this.reprojectTexture({texture:i,extent:t.extent},e,!0);a.texture.dispose();const o=document.createElement("canvas"),m=a.imageData;o.width=m.width,o.height=m.height;return o.getContext("2d").putImageData(m,0,0),{bitmapData:o,extent:a.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?(b._instanceRefCount--,0===b._instanceRefCount&&(this._quad.dispose(),this._program.dispose(),this._rctx.dispose(),b._instance=null)):(this._quad.dispose(),this._program.dispose())}}b._instanceRefCount=0;export{b as ImageReprojector};