UNPKG

@doegis/core

Version:

DOE GIS API

3 lines (1 loc) 14.7 kB
import e from"../../../../Color.js";import"../../../../symbols.js";import{result as t}from"../../../../core/asyncUtils.js";import i from"../../../../core/Error.js";import{isSome as r,get as s,isNone as a,unwrapOr as o,releaseMaybe as n,unwrap as l}from"../../../../core/maybe.js";import{throwIfAbortError as c,throwIfAborted as h}from"../../../../core/promiseUtils.js";import{pt2px as m,px2pt as u}from"../../../../core/screenUtils.js";import{dataComponents as d}from"../../../../core/urlUtils.js";import{c as _}from"../../../../chunks/mat4f64.js";import{f as p,a as f}from"../../../../chunks/vec2f64.js";import{Z as y,O as g,f as x}from"../../../../chunks/vec3f64.js";import{c as S}from"../../../../chunks/vec4.js";import{f as b,c as v}from"../../../../chunks/vec4f64.js";import{projectPointToVector as z}from"../../../../geometry/projection.js";import{containsPoint as P}from"../../../../geometry/support/aaBoundingBox.js";import{createRendererExpression as R}from"../../../../support/arcadeOnDemand.js";import{defaultPrimitive as C}from"../../../../symbols/support/IconSymbol3DLayerResource.js";import{getIconHref as M}from"../../../../symbols/support/utils.js";import j from"../../../2d/arcade/callExpressionWithFeature.js";import{TRANSPARENT_UNIT as I}from"./constants.js";import{perObjectElevationAligner as w}from"./ElevationAligners.js";import{SymbolUpdateType as O,elevationModeChangeUpdateType as T,needsElevationUpdates2D as E}from"./elevationAlignmentUtils.js";import{ElevationContext as U}from"./ElevationContext.js";import L from"./Graphics3DDrapedGraphicLayer.js";import{Graphics3DObject3DGraphicLayer as D}from"./Graphics3DObject3DGraphicLayer.js";import{Graphics3DSymbolLayer as F}from"./Graphics3DSymbolLayer.js";import{validateSymbolLayerSize as A}from"./graphicUtils.js";import{ApplyRendererDiffResult as G}from"./interfaces.js";import{namedAnchorToHUDMaterialAnchorPos as V}from"./placementUtils.js";import{placePointOnGeometry as B,createStageObject as N,extendPointGraphicElevationContext as k}from"./pointUtils.js";import{initFastSymbolUpdatesState as H,updateFastSymbolUpdatesState as q,evaluateModelTransform as W}from"../support/FastSymbolUpdates.js";import{createTexture as $,DEFAULT_SYMBOL_SIZE_RATIO as Z,DEFAULT_TEX_SIZE as J}from"../../support/engineContent/sdfPrimitives.js";import{DRAPED_Z as K}from"../../terrain/OverlayRenderer.js";import{PowerOfTwoResizeMode as Q}from"../../webgl-engine/lib/basicInterfaces.js";import{createPointGeometry as X}from"../../webgl-engine/lib/GeometryUtil.js";import{RenderGeometry as Y}from"../../webgl-engine/lib/RenderGeometry.js";import{Texture as ee}from"../../webgl-engine/lib/Texture.js";import{HUDMaterial as te}from"../../webgl-engine/materials/HUDMaterial.js";import ie from"../../../../symbols/CIMSymbol.js";const re=_(),se=x(0,0,1),ae=16,oe=1.5,ne=Z,le=[ne/2,ne/2,1-ne/2,1-ne/2],ce=[J*ne,J*ne];class he extends F{getCachedSize(){return{size:this._getIconSize()}}constructor(e,t,i,r){super(e,t,i,r),this._cimLayers=null,this._cimSymbolMaterials=new Map,this._cimSymbolTextures=new Map,this._cimMaterialParametersInfo=null,this._cimRequiredFields=null,this._cimScaleFactorOrFunction=null,this._size=null,this._symbolTextureRatio=1,this._outlineSize=0,this._elevationOptions={supportsOffsetAdjustment:!0,supportsOnTheGround:!0}}async doLoad(e){this._validateOrThrow();const t=this._prepareMaterialParameters(),i=this._getPrimitive();if(r(i))this._prepareResourcesPrimitive(t,i);else{const i=M(this.symbolLayer),r=d(i);r&&"application/json"===r.mediaType?await this._prepareResourcesCIM(t,JSON.parse(r.data),e):await this._prepareResourcesHref(t,i,e)}}_validateOrThrow(){if(this._drivenProperties.size)return;const e=A(this._getIconSize());if(e)throw new i("graphics3diconsymbollayer:invalid-size",e)}_getIconSize(){const e=this.symbolLayer,t=Math.round(null!=e.size?m(e.size):ae);return this._drivenProperties.size?Math.max(t,64):t}_generateTextureCIM(e){const t=this._getGraphicHash(e);let i=""===t?null:this._cimSymbolTextures.get(t);if(!i){const r={scaleFactor:this._cimScaleFactorOrFunction},s=this._context.sharedResources.cimSymbolRasterizer.rasterizeCIMSymbol3D(this._cimLayers,e,"esriGeometryPoint",r,void 0,void 0);this._cimMaterialParametersInfo.anchorPosition=this._getAnchorPos("relative",s.anchorPosition);const a={width:s.imageData.width,height:s.imageData.height,powerOfTwoResizeMode:Q.PAD};i=new ee(s.imageData,a),this._cimSymbolTextures.set(t,i),this._context.stage.add(i)}return i}_computeSize(e,t){const i=e.width/e.height;return i>1?[t,Math.round(t/i)]:[Math.round(t*i),t]}_prepareMaterialParameters(){const e={anchorPosition:this._getAnchorPos(this.symbolLayer.anchor,this.symbolLayer.anchorPosition)},t=this.symbol;if(me(t)){const{screenLength:i,minWorldLength:s,maxWorldLength:a}=t.verticalOffset;e.verticalOffset={screenLength:m(i),minWorldLength:s||0,maxWorldLength:r(a)?a:1/0}}return this._context.screenSizePerspectiveEnabled&&(e.screenSizePerspective=this._context.sharedResources.screenSizePerspectiveSettings),e.occlusionTest=!0,e.hasSlicePlane=this._context.slicePlaneEnabled,e}_prepareResourcesPrimitive(e,t){const i=this._getOutlineSize();if(ue(t)&&0===i)throw new Error("Nothing to render");if(this._outlineSize=i,e.color=this._getFillColor(),e.outlineColor=this._getOutlineColor(),e.outlineSize=this._outlineSize,r(this._context.sharedResources.textures)){const i=this._context.sharedResources.textures.fromData(`${t}-icon`,(()=>$(t)));this._texture=i.texture,this._releaseTexture=i,e.textureId=this._texture.id}e.textureIsSignedDistanceField=!0,e.distanceFieldBoundingBox=le;const s=this._getIconSize();this._size=[s,s],this._symbolTextureRatio=1/ne,this._createMaterialAndAddToStage(e,this._context.stage)}async _prepareResourcesHref(e,s,a){this._outlineSize=this._getOutlineSize(),e.color=this._getFillColor(),e.outlineColor=this._getOutlineColor(),e.outlineSize=this._outlineSize,e.textureIsSignedDistanceField=!1;const o=this._getIconSize(),n=o*this._context.graphicsCoreOwner.view.state.rasterPixelRatio;if(r(this._context.sharedResources.textures)){const r=await t(this._context.sharedResources.textures.fromUrl(s,n,{signal:a}));if(!1===r.ok){c(r.error);throw new i("graphics3diconsymbollayer:request-failed",`Failed to load (Request for icon resource failed: ${s})`)}this._releaseTexture=r.value;const l=r.value.texture,h=l.params;this._size=this._computeSize(h,o),e.textureId=l.id}this._createMaterialAndAddToStage(e,this._context.stage)}async _prepareResourcesCIM(e,t,i){const r=new ie({data:t});if(!this._context.sharedResources.cimSymbolRasterizer){const e=(await import("../../../../symbols/cim/CIMSymbolRasterizer.js")).CIMSymbolRasterizer;h(i),this._context.sharedResources.cimSymbolRasterizer||(this._context.sharedResources.cimSymbolRasterizer=new e(this._context.renderCoordsHelper.spatialReference,!0))}const s=this._context.layer.fields?this._context.layer.fields.map((e=>e.toJSON())):null;let a,o;if(this._cimLayers=await this._context.sharedResources.cimSymbolRasterizer.analyzeCIMSymbol(r,s,this._context.renderer&&"dictionary"===this._context.renderer.type?this._context.renderer.fieldMap:null,"esriGeometryPoint",{signal:i}),this._context.renderer&&"dictionary"===this._context.renderer.type&&this._context.renderer.scaleExpression){const e=this._context.renderer;if(isNaN(e.scaleExpression)){const t=e.scaleExpression,i=await R(t,this._context.layer.spatialReference,s);o=(e,t,r)=>{const s=j(i,e,{$view:r},"esriGeometryPoint",t);return null!==s?s:1}}else a=Number(e.scaleExpression)}this._cimScaleFactorOrFunction=a||o||1;const n=this._context.renderer?await this._context.renderer.getRequiredFields(this._context.layer.fieldsIndex):[];h(i);const l=this._context.layer.fieldsIndex;this._cimRequiredFields=n.map((e=>l.get(e).name)),this._cimMaterialParametersInfo=e,this._cimMaterialParametersInfo.color=this._getFillColor(),this._cimMaterialParametersInfo.outlineColor=[0,0,0,0],this._cimMaterialParametersInfo.outlineSize=0,this._cimMaterialParametersInfo.textureIsSignedDistanceField=!1}_getPrimitive(){return this.symbolLayer.resource&&this.symbolLayer.resource.href?null:this.symbolLayer.resource&&this.symbolLayer.resource.primitive||C}_getOutlineSize(){let e=0;const t=this.symbolLayer;if(r(t.outline)&&null!=t.outline.size)return Math.max(m(t.outline.size),0);return e=ue(this._getPrimitive())?oe:0,Math.max(e,0)}_getOutlineColor(){const t=this._getLayerOpacity(),i=this.symbolLayer,a=s(i,"outline","color");if(r(a)){const i=e.toUnitRGB(a),r=a.a*t;return[i[0],i[1],i[2],r]}return[0,0,0,0]}_getFillColor(){if(ue(this._getPrimitive()))return I;const e=a(this._getPrimitive()),t=s(this.symbolLayer,"material","color");return this._getCombinedOpacityAndColor(t,{hasIntrinsicColor:e})}_getAnchorPos(e,t){return"relative"===e?p((t.x||0)+.5,.5-(t.y||0)):e in V?V[e]:V.center}_createMaterialAndAddToStage(e,t){if(this._cimLayers?this._fastUpdates={enabled:!1}:this._fastUpdates=H(this._context.renderer,this._fastVisualVariableConvertOptions()),this._fastUpdates.enabled&&Object.assign(e,this._fastUpdates.materialParameters),this._cimLayers){let i=r(e.textureId)?this._cimSymbolMaterials.get(e.textureId):null;return i||(i=new te(e),this._cimSymbolMaterials.set(o(e.textureId,0),i),t.add(i)),i}return this._material=new te(e),t.add(this._material),this._material}_setDrapingDependentMaterialParameters(){this.draped&&(this._forEachMaterial((e=>{e.setParameters({verticalOffset:null,screenSizePerspective:null,occlusionTest:!1,hasSlicePlane:!1,shaderPolygonOffset:0,isDraped:this.draped})})),this.layerOpacityChanged())}destroy(){super.destroy(),this._forEachMaterial((e=>this._context.stage.remove(e))),this._material=null,this._cimSymbolMaterials.clear(),this._cimSymbolTextures.forEach((e=>this._context.stage.remove(e))),this._cimSymbolTextures.clear(),this._releaseTexture=n(this._releaseTexture)}_getScaleFactor(e,t){if(this._drivenProperties.size&&e.size){for(let t=0;t<3;t++){const i=e.size[t];i&&"symbol-value"!==i&&"proportional"!==i&&(e.size[t]=m(i))}if("symbol-value"===e.size[0])return 1;if(isFinite(+e.size[0]))return+e.size[0]/t;if(isFinite(+e.size[2]))return+e.size[2]/t}return 1}createGraphics3DGraphic(e){const t=e.graphic;if(!this._validateGeometry(t.geometry))return null;let i,r=[0,0];if(this._cimLayers){if(!this._cimLayers.length)return null;const e=this._generateTextureCIM(t),s={textureId:e.id,...this._cimMaterialParametersInfo};i=this._createMaterialAndAddToStage(s,this._context.stage),r=[e.params.width,e.params.height]}else r=this._size,i=l(this._material);const s=B(t.geometry);if(a(s))return this.logger.warn(`unsupported geometry type for icon symbol: ${t.geometry.type}`),null;const o=e.renderingInfo,n=this._getVertexOpacityAndColor(o);let c=1;if(!this._fastUpdates.enabled||!this._fastUpdates.visualVariables.size){const e=r[0]>r[1]?r[0]:r[1];c=this._getScaleFactor(o,e)}c*=this._symbolTextureRatio;const h=p(r[0]*c,r[1]*c),m=this.setGraphicElevationContext(t,new U);return this.ensureDrapedStatus("on-the-ground"===m.mode)&&this._setDrapingDependentMaterialParameters(),this.draped?this._createAsOverlay(t,s,i,n,h,e.layer.uid):this._createAs3DShape(t,s,i,n,h,m,t.uid)}layerOpacityChanged(){const e=this._getFillColor(),t=this._getOutlineColor();this._forEachMaterial((i=>{i.setParameters({color:e}),i.setParameters({outlineColor:t})}))}layerElevationInfoChanged(e,t,i){const r=this._elevationContext.mode,s=T(he.elevationModeChangeTypes,i,r);if(s!==O.UPDATE)return s;const a=E(r)||"absolute-height"===r;return this.updateGraphics3DGraphicElevationInfo(e,t,(()=>a))}slicePlaneEnabledChanged(){return this.draped||this._forEachMaterial((e=>{e.setParameters({hasSlicePlane:this._context.slicePlaneEnabled})})),!0}physicalBasedRenderingChanged(){return!0}pixelRatioChanged(){return!!this._getPrimitive()}skipHighSymbolLodsChanged(){return!0}applyRendererDiff(e,t){for(const i in e.diff){if("visualVariables"!==i)return G.Recreate_Symbol;if(!q(this._fastUpdates,t,this._fastVisualVariableConvertOptions()))return G.Recreate_Symbol;r(this._material)&&this._material.setParameters(this._fastUpdates.materialParameters)}return G.Fast_Update}_defaultElevationInfoNoZ(){return de}_createAs3DShape(e,t,i,r,s,o,n){const l=this.getFastUpdateAttrValues(e),c=l?e=>W(this._fastUpdates.materialParameters,l,e):void 0,h=this._context.layer.uid,m=this._context.stage.renderView.getObjectAndLayerIdColor({graphicUid:n,layerUid:h}),u=X(i,se,null,r,s,_e,null,l,m),d=N(this._context,t,u,o,n,c);if(a(d))return null;const _=new D(this,d.object,[u],null,null,w,o);return _.alignedSampledElevation=d.sampledElevation,_.needsElevationUpdates=E(o.mode)||"absolute-height"===o.mode,_.getScreenSize=this._createScreenSizeGetter(s,c),_.calculateRelativeScreenBounds=e=>i.calculateRelativeScreenBounds(_.getScreenSize(),1,e),k(_,t,this._context.elevationProvider),_}_createAsOverlay(e,t,i,s,a,o){i.renderPriority=this._renderPriority;const n=v();z(t,n,this._context.overlaySR),n[2]=K;const l=this._context.clippingExtent;if(r(l)&&!P(l,n))return null;const c=this.getFastUpdateAttrValues(e),h=c?e=>W(this._fastUpdates.materialParameters,c,e):void 0,m=this._context.stage.renderView.getObjectAndLayerIdColor({graphicUid:e.uid,layerUid:this._context.layer.uid}),u=X(i,se,n,s,a,null,null,c,m),d=new Y(u,{layerUid:o,graphicUid:e.uid,shaderTransformer:h});n[3]=0,S(d.boundingSphere,n);const _=new L(this,[d],null,this._context.drapeSourceRenderer);return _.getScreenSize=this._createScreenSizeGetter(a,h),_.calculateRelativeScreenBounds=e=>i.calculateRelativeScreenBounds(_.getScreenSize(),1,e),_}_createScreenSizeGetter(e,t){const i=this._outlineSize+2;if(this._fastUpdates.enabled){const r=e[0]/this._symbolTextureRatio,s=e[1]/this._symbolTextureRatio;return(e=f())=>{const a=t(re);return e[0]=a[0]*r+i,e[1]=a[5]*s+i,e}}{const t=e[0]/this._symbolTextureRatio+i,r=e[1]/this._symbolTextureRatio+i;return(e=f())=>(e[0]=t,e[1]=r,e)}}_fastVisualVariableConvertOptions(){const e=this._size[0]>this._size[1]?this._size[0]:this._size[1],t=x(e,e,e),i=u(1),r=e*i;return{modelSize:t,symbolSize:x(r,r,r),unitInMeters:i,transformation:{anchor:y,scale:g,rotation:y}}}_getGraphicHash(e){let t="";for(const i of this._cimRequiredFields)t+=i+e.attributes[i];return t}_forEachMaterial(e){r(this._material)&&e(this._material),this._cimSymbolMaterials.forEach(e)}test(){return{...super.test(),material:this._material}}}function me(e){return e&&"point-3d"===e.type&&e.hasVisibleVerticalOffset()}function ue(e){return!a(e)&&("cross"===e||"x"===e)}he.PRIMITIVE_SIZE=ce,he.elevationModeChangeTypes={definedChanged:O.UPDATE,staysOnTheGround:O.NONE,onTheGroundChanged:O.RECREATE};const de={mode:"relative-to-ground",offset:0},_e=b(0,0,0,1);export{he as Graphics3DIconSymbolLayer};