UNPKG

@arcgis/core

Version:

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

6 lines (5 loc) • 14.2 kB
/* 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"../../core/has.js";import r from"../../core/JSONSupport.js";import t from"../../core/Logger.js";import{property as s}from"../../core/accessorSupport/decorators/property.js";import"../../core/RandomLCG.js";import{subclass as a}from"../../core/accessorSupport/decorators/subclass.js";import o from"../../layers/support/RasterInfo.js";import{colorize as n,remapColor as i,lookupPixels as l,createColormapLUT as u,isValidPixelBlock as c}from"../../layers/support/rasterFunctions/pixelUtils.js";import{stretch as p,getStretchCutoff as d,isStandardU8Histogram as m,createStretchLUT as h,computeGammaValues as f,createHistogramEqualizationLUT as b}from"../../layers/support/rasterFunctions/stretchUtils.js";import{hillshade as g,tintHillshade as y,calculateHillshadeParams as S}from"../../layers/support/rasterFunctions/surfaceUtils.js";import{convertColorRampToColormap as x,createHsvMap as R}from"./colorRampUtils.js";import{isUVRendererSupported as I,isColormapSupportedByWebGL as k,isColormapRendererSupported as C,isShadedReliefRendererSupported as L}from"./rasterRendererChecks.js";let _=class extends r{constructor(e){super(e),this.lookup={rendererJSON:{}},this.canRenderInWebGL=!1}bind(){const{rendererJSON:e}=this;if(!e)return{success:!1};let r;switch(this.lookup={rendererJSON:{}},e.type){case"uniqueValue":r=this._updateUVRenderer(e);break;case"rasterColormap":r=this._updateColormapRenderer(e);break;case"rasterStretch":r=this._updateStretchRenderer(e);break;case"classBreaks":r=this._updateClassBreaksRenderer(e);break;case"rasterShadedRelief":r=this._updateShadedReliefRenderer(e);break;case"vectorField":r=this._updateVectorFieldRenderer();break;case"flowRenderer":r=this._updateFlowRenderer()}return r}symbolize(e){let r=e?.pixelBlock;if(!T(r))return r;if(e.simpleStretchParams&&"rasterStretch"===this.rendererJSON.type)return this.simpleStretch(r,e.simpleStretchParams);try{let t;switch(r.pixels.length>3&&(r=r.extractBands(e.bandIds??[0,1,2])),this.rendererJSON.type){case"uniqueValue":case"rasterColormap":t=this._symbolizeColormap(r);break;case"classBreaks":t=this._symbolizeClassBreaks(r);break;case"rasterStretch":t=this._symbolizeStretch(r,e.bandIds);break;case"rasterShadedRelief":{const s=e.extent,a=s.spatialReference.isGeographic,o={x:(s.xmax-s.xmin)/r.width,y:(s.ymax-s.ymin)/r.height};t=this._symbolizeShadedRelief(r,{isGCS:a,resolution:o});break}}return t}catch(s){return t.getLogger(this).error("symbolize",s.message),r}}simpleStretch(e,r){if(!T(e))return e;try{return e.pixels.length>3&&(e=e.extractBands([0,1,2])),p(e,{...r,isRenderer:!0})}catch(s){return t.getLogger(this).error("symbolize",s.message),e}}generateWebGLParameters(e){const{rendererJSON:r}=this;switch(r.type){case"uniqueValue":case"rasterColormap":case"classBreaks":return this._generateColormapWebGLParams("classBreaks"===r.type);case"rasterStretch":return this._generateStretchWebGLParams(e.pixelBlock,r,e.bandIds);case"rasterShadedRelief":return this._generateShadedReliefWebGLParams(r,e.isGCS,e.resolution??void 0);case"vectorField":return this._generateVectorFieldWebGLParams(r);default:return null}}_isLUTChanged(e){const r=this.lookup.rendererJSON;if(!r)return!0;const{rendererJSON:t}=this;if("colorRamp"in t&&t.colorRamp){const s=t.colorRamp;if(e)return JSON.stringify(s)!==JSON.stringify(r.colorRamp)}return JSON.stringify(t)!==JSON.stringify(r)}_symbolizeColormap(e){if(this._isLUTChanged()){if(!this.bind().success)return e}return n(e,this.lookup.colormapLut)}_symbolizeClassBreaks(e){const{canUseIndexedLUT:r}=this._analyzeClassBreaks(this.rendererJSON);if(this._isLUTChanged()){if(!this.bind().success)return e}return r?n(e,this.lookup.colormapLut):i(e,this.lookup.remapLut??[])}_symbolizeStretch(e,r){if(!e)return null;const{rasterInfo:t,lookup:s}=this,{pixelType:a,bandCount:o}=t,i=this.rendererJSON,u=["u8","u16","s8","s16"].includes(a);let c;const{dra:f}=i,{gamma:b}=s;if(f&&(r=null),"histogramEqualization"===i.stretchType){const a=f?null:s.histogramLut,o=d(i,{rasterInfo:t,pixelBlock:e,bandIds:r,returnHistogramLut:!a}),n="u8"===t.pixelType&&!f&&m(t.histograms?.[0])?e:p(e,{...o,gamma:b,isRenderer:!0});c=l(n,{lut:f?o.histogramLut:r?.length?r.map((e=>a[e])):a,offset:0})}else if(u){let n;if(f){const s=d(i,{rasterInfo:t,pixelBlock:e,bandIds:r});n=h({pixelType:a,...s,gamma:b,rounding:"floor"})}else{if(this._isLUTChanged()){if(!this.bind().success)return e}n=s.stretchLut}if(!n)return e;o>1&&null!=r&&r.length===e?.pixels.length&&n.lut.length===o&&(n={lut:r.map((e=>n.lut[e])),offset:n.offset}),c=l(e,n)}else{const s=d(i,{rasterInfo:t,pixelBlock:e,bandIds:r});c=p(e,{...s,gamma:b,isRenderer:!0})}if(i.colorRamp){if(this._isLUTChanged(!0)){if(!this.bind().success)return e}c=n(c,s.colormapLut)}return c}_symbolizeShadedRelief(e,r){const t=this.rendererJSON,s={...t,...r},a=g(e,s);if(!t.colorRamp)return a;if(this._isLUTChanged(!0)){if(!this.bind().success)return a}const{hsvMap:o}=this.lookup;if(!o)return a;const n=this.rasterInfo.statistics?.[0]??{min:0,max:8e3};return y(a,e,o,n),a}_isVectorFieldData(){const{bandCount:e,dataType:r}=this.rasterInfo;return 2===e&&("vector-magdir"===r||"vector-uv"===r)}_updateVectorFieldRenderer(){return this._isVectorFieldData()?{success:!0}:{success:!1,error:`Unsupported data type "${this.rasterInfo.dataType}"; VectorFieldRenderer only supports "vector-magdir" and "vector-uv".`}}_updateFlowRenderer(){return this._isVectorFieldData()?{success:!0}:{success:!1,error:`Unsupported data type "${this.rasterInfo.dataType}"; FlowRenderer only supports "vector-magdir" and "vector-uv".`}}_updateUVRenderer(e){const{bandCount:r,attributeTable:t,pixelType:s}=this.rasterInfo,a=e.field1;if(!a)return{success:!1,error:"Unsupported renderer; missing UniqueValueRenderer.field."};const o=e.defaultSymbol,n=1===r&&["u8","s8"].includes(s);if(!I(this.rasterInfo,a)&&!n)return{success:!1,error:"Unsupported data; UniqueValueRenderer is only supported on single band data with a valid raster attribute table."};const i=[];if(null!=t){const r=t.fields.find((e=>"value"===e.name.toLowerCase()));if(!r)return{success:!1,error:"Unsupported data; the data's raster attribute table does not have a value field."};t.features.forEach((t=>{const s=e.uniqueValueInfos?.find((e=>String(e.value)===String(t.attributes[a]))),n=s?.symbol?.color;n?i.push([t.attributes[r.name]].concat(n)):o&&i.push([t.attributes[r.name]].concat(o.color))}))}else{if("value"!==a.toLowerCase())return{success:!1,error:'Unsupported renderer; UniqueValueRenderer.field must be "Value" when raster attribute table is not available.'};e.uniqueValueInfos?.forEach((e=>{const r=e?.symbol?.color;r?i.push([parseInt(""+e.value,10)].concat(r)):o&&i.push([parseInt(""+e.value,10)].concat(o?.color))}))}if(0===i.length)return{success:!1,error:"Invalid UniqueValueRenderer. Cannot find matching records in the raster attribute table."};const l=u({colormap:i});return this.lookup={rendererJSON:e,colormapLut:l},this.canRenderInWebGL=k(l?.indexedColormap),{success:!0}}_updateColormapRenderer(e){if(!C(this.rasterInfo))return{success:!1,error:"Unsupported data; the data source does not have a colormap."};const r=e.colormapInfos.map((e=>[e.value].concat(e.color))).sort(((e,r)=>e[0]-r[0]));if(!r||0===r.length)return{success:!1,error:"Unsupported renderer; ColormapRenderer must have meaningful colormapInfos."};const t=u({colormap:r});return this.lookup={rendererJSON:e,colormapLut:t},this.canRenderInWebGL=k(t?.indexedColormap),{success:!0}}_updateShadedReliefRenderer(e){if(!L(this.rasterInfo))return{success:!1,error:`Unsupported data type "${this.rasterInfo.dataType}"; ShadedReliefRenderer only supports "elevation", or single band float/s16 data.`};if(e.colorRamp){const r=x(e.colorRamp,{interpolateAlpha:!0}),t=u({colormap:r}),s=R(t.indexedColormap);this.lookup={rendererJSON:e,colormapLut:t,hsvMap:s}}else this.lookup={rendererJSON:e};return this.canRenderInWebGL=!0,{success:!0}}_analyzeClassBreaks(e){const{attributeTable:r,pixelType:t}=this.rasterInfo,s=r?.fields.find((e=>"value"===e.name.toLowerCase())),a=r?.fields.find((r=>r.name.toLowerCase()===e.field.toLowerCase())),o=null!=s&&null!==a;return{canUseIndexedLUT:["u8","u16","s8","s16"].includes(t)||o,tableValueField:s,tableBreakField:a}}_updateClassBreaksRenderer(e){const{attributeTable:r}=this.rasterInfo,{canUseIndexedLUT:t,tableValueField:s,tableBreakField:a}=this._analyzeClassBreaks(e),o=e.classBreakInfos;if(!o?.length)return{success:!1,error:"Unsupported renderer; missing or invalid ClassBreaksRenderer.classBreakInfos."};const n=o.sort(((e,r)=>e.classMaxValue-r.classMaxValue)),i=n[n.length-1];let l=e.minValue;if(!t){const r=[];for(let e=0;e<n.length;e++)r.push({value:n[e].classMinValue??l,mappedColor:n[e].symbol.color}),l=n[e].classMaxValue;return r.push({value:i.classMaxValue,mappedColor:i.symbol.color}),this.lookup={rendererJSON:e,remapLut:r},this.canRenderInWebGL=!1,{success:!0}}const c=[];if(null!=r&&null!=s&&null!==a&&s!==a){const t=s.name,o=a.name,i=n[n.length-1],{classMaxValue:u}=i;l=e.minValue;for(const e of r.features){const r=e.attributes[t],s=e.attributes[o],a=s===u?i:s<l?null:n.find((({classMaxValue:e})=>e>s));a&&c.push([r].concat(a.symbol.color))}}else{l=Math.floor(e.minValue);for(let e=0;e<n.length;e++){const r=n[e];for(let e=l;e<r.classMaxValue;e++)c.push([e].concat(r.symbol.color));l=Math.ceil(r.classMaxValue)}i.classMaxValue===l&&c.push([i.classMaxValue].concat(i.symbol.color))}const p=u({colormap:c,fillUnspecified:!1});return this.lookup={rendererJSON:e,colormapLut:p},this.canRenderInWebGL=k(p?.indexedColormap),{success:!0}}_updateStretchRenderer(e){let{stretchType:r,dra:t}=e;if(!("none"===r||e.statistics?.length||v(this.rasterInfo.statistics)||t))return{success:!1,error:"Unsupported renderer; StretchRenderer.statistics is required when dynamic range adjustment is not used."};const s=e.histograms||this.rasterInfo.histograms;!V(e.stretchType)||s?.length||t||(r="minMax");const{computeGamma:a,useGamma:o,colorRamp:n}=e;let{gamma:i}=e;if(o&&a&&!i?.length){const r=e.statistics?.length?e.statistics:this.rasterInfo.statistics;i=f(this.rasterInfo.pixelType,r)}const l=this.rasterInfo.pixelType,c=!t&&["u8","u16","s8","s16"].includes(l);if("histogramEqualization"===r){const r=s.map((e=>b(e)));this.lookup={rendererJSON:e,histogramLut:r}}else if(c){const r=d(e,{rasterInfo:this.rasterInfo}),t=h({pixelType:l,...r,gamma:o?i:null,rounding:"floor"});this.lookup={rendererJSON:e,stretchLut:t}}else this.lookup={rendererJSON:e};if(n&&!O(n)){const r=x(n,{interpolateAlpha:!0});this.lookup.colormapLut=u({colormap:r}),this.lookup.rendererJSON=e}return this.lookup.gamma=o&&i?.length?i:null,this.canRenderInWebGL="histogramEqualization"!==r,{success:!0}}_generateColormapWebGLParams(e){const{indexedColormap:r,offset:t}=this.lookup.colormapLut||{};return{colormap:r,colormapOffset:t,isClassBreaks:e,type:"lut"}}_generateStretchWebGLParams(e,r,t){const{colormapLut:s}=this.lookup,a=r.colorRamp?s?.indexedColormap:null,o=r.colorRamp?s?.offset:null;"histogramEqualization"===r.stretchType&&(r={...r,stretchType:"minMax"});const{gamma:n}=this.lookup,i=!(!r.useGamma||!n?.some((e=>1!==e))),{minCutOff:l,maxCutOff:u,minOutput:c,maxOutput:p}=d(r,{rasterInfo:this.rasterInfo,pixelBlock:e,bandIds:t});let m=0;null!=e&&(m=e.getPlaneCount(),2===m&&((e=e.clone()).statistics=[e.statistics[0]],e.pixels=[e.pixels[0]]));const{bandCount:h}=this.rasterInfo,f=Math.min(3,t?.length||m||h,h),b=a||i?1:255,g=new Float32Array(f);if(i&&n)for(let d=0;d<f;d++)n[d]>1?n[d]>2?g[d]=6.5+(n[d]-2)**2.5:g[d]=6.5+100*(2-n[d])**4:g[d]=1;1===l.length&&(l[2]=l[1]=l[0]),1===u.length&&(u[2]=u[1]=u[0]);const y=i&&n?[n[0],n[1]??n[0],n[2]??n[0]]:[1,1,1],S=i?[g[0],g[1]??g[0],g[2]??g[0]]:[1,1,1],x=u.map(((e,r)=>u[r]===l[r]?0:(p-c)/(u[r]-l[r])/b));return{bandCount:f,minOutput:c/b,maxOutput:p/b,minCutOff:l,maxCutOff:u,factor:x,useGamma:i,gamma:y,gammaCorrection:S,colormap:a,colormapOffset:o,stretchType:r.stretchType,type:"stretch"}}_generateShadedReliefWebGLParams(e,r=!1,t={x:0,y:0}){const{colormapLut:s}=this.lookup,a=e.colorRamp?s?.indexedColormap:null,o=e.colorRamp?s?.offset:null,n={...e,isGCS:r,resolution:t},i=S(n),l=this.rasterInfo.statistics?.[0];return{...i,minValue:l?.min??0,maxValue:l?.max??8e3,hillshadeType:"traditional"===e.hillshadeType?0:1,type:"hillshade",colormap:a,colormapOffset:o}}_generateVectorFieldWebGLParams(e){const{style:r,inputUnit:t,outputUnit:s,visualVariables:a,symbolTileSize:o,flowRepresentation:n}=e,i=this.rasterInfo.statistics?.[0].min??0,l=this.rasterInfo.statistics?.[0].max??50,u=a?.find((e=>"sizeInfo"===e.type))??{maxDataValue:l,maxSize:.8*o,minDataValue:i,minSize:.2*o},c=u.minDataValue??i,p=u.maxDataValue??l,d=null!=u.maxSize&&null!=u.minSize?[u.minSize/o,u.maxSize/o]:[.2,.8];if("wind_speed"===r){const e=(d[0]+d[1])/2;d[0]=d[1]=e}const m=null!=c&&null!=p?[c,p]:null;let h=null;if("classified_arrow"===r)if(null!=c&&null!=p&&null!=u){h=[];const e=(u.maxDataValue-u.minDataValue)/5;for(let r=0;r<6;r++)h.push(u.minDataValue+e*r)}else h=[0,1e-6,3.5,7,10.5,14];const f="flow_to"===n===("ocean_current_kn"===r||"ocean_current_m"===r)?0:Math.PI,b=a?.find((e=>"rotationInfo"===e.type));return{breakValues:h,dataRange:m,inputUnit:t,outputUnit:s,symbolTileSize:o,symbolPercentRange:d,style:r||"single_arrow",rotation:f,rotationType:this.rasterInfo.storageInfo?.tileInfo&&"vector-uv"===this.rasterInfo.dataType?"geographic":b?.rotationType||e.rotationType,type:"vectorField"}}};function V(e){return"percentClip"===e||"histogramEqualization"===e}function v(e){return null!=e&&e.length>0&&null!=e[0].min&&null!=e[0].max}function T(e){return c(e)&&0!==e.validPixelCount}function O(e){return"algorithmic"===e.type&&["0,0,0,255","0,0,0"].includes(e.fromColor.join(","))&&["255,255,255,255","255,255,255"].includes(e.toColor.join(","))}e([s({json:{write:!0}})],_.prototype,"rendererJSON",void 0),e([s({type:o,json:{write:!0}})],_.prototype,"rasterInfo",void 0),e([s({json:{write:!0}})],_.prototype,"lookup",void 0),e([s()],_.prototype,"canRenderInWebGL",void 0),_=e([a("esri.renderers.support.RasterSymbolizer")],_);export{_ as default};