@doegis/core
Version:
DOE GIS API
3 lines (1 loc) • 14.9 kB
JavaScript
import e from"../../../../core/Error.js";import has from"../../../../core/has.js";import t from"../../../../core/Logger.js";import{isSome as r,unwrap as i,isNone as n,unwrapOr as s}from"../../../../core/maybe.js";import{pt2px as l}from"../../../../core/screenUtils.js";import{sqlAnd as o}from"../../../../core/sql.js";import{diff as a}from"../../../../core/accessorSupport/diffUtils.js";import{validateLabelingInfo as u}from"../../../../layers/support/labelingInfo.js";import{WGLSymbologyType as d}from"../../engine/webgl/enums.js";import{getVVType as f}from"../../engine/webgl/Utils.js";import{getTechniqueFromRenderer as p}from"../../engine/webgl/techniques/utils.js";import{getVVFlags as c}from"../../engine/webgl/util/vvFlagUtils.js";import{createSymbolSchema as y}from"./createSymbolSchema.js";import{getPtMaxVVSize as m}from"./support/pixelBuffering.js";import{getSupportedHeatmapRenderer as g,simplifyVisualVariables as b}from"./support/rendererUtils.js";import{injectDynamicLevelDependentSizeVisualVariable as x,createClusterRenderer as v}from"../support/clusterUtils.js";import{toJSONGeometryType as h}from"../support/util.js";const T=t.getLogger("esri.views.2d.layers.features.schemaUtils"),S="ValidationError";function E(e){return e}function w(e,t){let i=0,n=0,s=d.DEFAULT;if(r(e)){if(n=m(e,t),"visualVariables"in e&&(i=c(e.visualVariables||[]),"dot-density"===e.type&&(s=d.DOT_DENSITY)),"heatmap"===e.type&&(s=d.HEATMAP),"dictionary"===e.type)return{maxVVSize:n,vvFlags:i,symbologyType:d.DEFAULT};if("pie-chart"===e.type)return{maxVVSize:n,vvFlags:i,symbologyType:d.PIE_CHART};if(s!==d.DOT_DENSITY&&s!==d.HEATMAP){const t=e.getSymbols();"backgroundFillSymbol"in e&&e.backgroundFillSymbol&&t.push(e.backgroundFillSymbol);let r=!0,i=!0;for(const e of t)if("cim"===e.type&&(i=!1),"simple-fill"===e.type||"picture-fill"===e.type){const t=e.outline,n=t&&"none"!==t.style&&"solid"!==t.style,s="simple-fill"===e.type&&"none"!==e.style&&"solid"!==e.style;n&&(r=!1),("picture-fill"===e.type||s||n)&&(i=!1)}r?s=i?d.OUTLINE_FILL_SIMPLE:d.OUTLINE_FILL:i&&(s=d.SIMPLE)}}return{vvFlags:i,maxVVSize:n,symbologyType:s}}let F=null;function I(e){if(has("esri-2d-update-debug")){const t=V(e,!0);console.debug("Created new schema",t),console.debug("Schema diff",a(F,t)),F=t}return V(e)}function V(e,t=!1){try{const n=A(e,t),s=C(e),l={};n.map((t=>O(l,e,t)));const a=r(e.subtypeCode)?`${e.subtypeField} = ${e.subtypeCode}`:null,u=i(o(e.definitionExpression,a));return{source:{definitionExpression:u,fields:e.fields.map((e=>e.toJSON())),gdbVersion:e.gdbVersion,historicMoment:e.historicMoment?.getTime(),outFields:e.availableFields,pixelBuffer:e.pixelBuffer,spatialReference:e.spatialReference.toJSON(),timeExtent:e.timeExtent?.toJSON(),customParameters:e.customParameters},attributes:{fields:{},indexCount:0},processors:n,tileRenderer:s,targets:l}}catch(n){if(n.fieldName===S)return T.error(n),null;throw n}}function O(t,r,i){switch(i.target){case"feature":return void L(t,N(r),i);case"aggregate":{if(!("featureReduction"in r))return;const n=r.featureReduction;switch(n?.type){case"selection":throw new e(S,"Mapview does not support `selection` reduction type",n);case"binning":return L(t,N(r),i),void j(t,n,r.fields.map((e=>e.toJSON())),i);case"cluster":return L(t,N(r),i),void R(t,n,r.fields.map((e=>e.toJSON())),i)}}}}function z(e,t){for(const r in t){const i=t[r];if(i.target!==e.name)continue;const n=e.attributes[r];if(n?.context){const e=n.context;e.mesh=e.mesh||i.context?.mesh,e.storage=e.storage||i.context?.storage}else e.attributes[r]=i}return e}function N(e){return[i(e.filter)?.toJSON()??null,i(i(e.featureEffect)?.filter)?.toJSON()??null]}function L(e,t,r){return e.feature||(e.feature={name:"feature",input:"source",filters:t,attributes:{}}),z(e.feature,r.attributes.fields),e}function M(t,r){const{onStatisticExpression:i,onStatisticField:n,statisticType:s}=t;switch(s){case"min":case"max":case"avg":case"avg_angle":case"sum":case"count":return"esriFieldTypeDouble";case"mode":{if(i){const{returnType:r}=i;return r?"string"===r?"esriFieldTypeString":"esriFieldTypeDouble":(T.error(new e(S,"Unable to infer type of aggregateField with onStatisticExpression. ReturnType is not defined",t)),"esriFieldTypeString")}const s=r.find((e=>e.name===n));return s?s.type:(T.error(new e(S,"Unable to infer type of aggregateField with onStatisticExpression. ReturnType is not defined",t)),"esriFieldTypeString")}}}function j(e,t,r,i){return e.aggregate||(e.aggregate={name:"aggregate",type:"bin",filters:null,input:"feature",params:{fixedBinLevel:t.fixedBinLevel,fields:(t.fields??[]).map((e=>({...e.toJSON(),type:M(e,r)})))},attributes:{}}),z(e.aggregate,i.attributes.fields),e}function R(e,t,r,i){return e.aggregate||(e.aggregate={name:"aggregate",type:"cluster",input:"feature",filters:null,attributes:{},params:{clusterRadius:l(t.clusterRadius/2),clusterPixelBuffer:64*Math.ceil(l(t.clusterMaxSize)/64),fields:(t.fields??[])?.map((e=>({...e.toJSON(),type:M(e,r)})))}}),z(e.aggregate,i.attributes.fields),e}function U(e,t){return t.field?B(e,{...t,type:"field",field:t.field}):t.valueExpression?B(e,{...t,type:"expression",valueExpression:t.valueExpression}):{field:void 0,fieldIndex:void 0}}function B(e,t){switch(t.type){case"expression":{const r=E(t.valueExpression);if(!e.fields[r]){const i=e.indexCount++;e.fields[r]={...t,name:r,fieldIndex:i}}return{fieldIndex:e.fields[r].fieldIndex}}case"label-expression":{const r=E(JSON.stringify(t.label));if(!e.fields[r]){const i=e.indexCount++;e.fields[r]={...t,name:r,fieldIndex:i}}return{fieldIndex:e.fields[r].fieldIndex}}case"field":{const r=t.field;return"aggregate"===t.target&&e.fields[r]||(e.fields[r]={...t,name:r}),{field:r}}case"statistic":return e.fields[t.name]={...t},{field:t.name}}}function A(e,t=!1){const r=new Array;let i=0;return r.push(k(e,i++,t)),r}function D(e,t,r,i,n,s=!1){const l=B(e,{type:"label-expression",target:r,context:{mesh:!0},resultType:"string",label:{labelExpression:t.labelExpression,labelExpressionInfo:t.labelExpressionInfo?{expression:t.labelExpressionInfo.expression}:null,symbol:!!t.symbol,where:t.where}}),{fieldIndex:o}=l;return{...y(t,n,s),fieldIndex:o,target:r,index:i}}function P(t,r,i){const n="featureReduction"in r&&r.featureReduction;if(!n)return{fields:[],labels:[],matcher:void 0,rendererOverride:void 0};const s="aggregate",l=[];let o=null,a=h(r.geometryType),d=[],f=null;if(n)switch(n.type){case"selection":return T.error(new e(S,"Mapview does not support `selection` reduction type",n)),{fields:[],labels:[],matcher:void 0,rendererOverride:void 0};case"cluster":case"binning":if(l.push(...n.fields??[]),"cluster"===n.type?a="esriGeometryPoint":"binning"===n.type&&(a="esriGeometryPolygon"),n.renderer&&!n.renderer.authoringInfo?.isAutoGenerated){if("cluster"===n.type){const{renderer:e}=x(n.renderer,n,null);f=e}else f=n.renderer;const e=w(n.renderer,n);o=$(t,s,n.renderer,e,i),d=n&&n.labelsVisible&&n.labelingInfo||[]}else if("cluster"===n.type){if(f=v(l,r.renderer,n,null,!0),n.symbol){const e=w(f,n);o={type:"simple",symbol:y(n.symbol,e,i),symbologyType:e.symbologyType}}d=n&&n.labelsVisible&&n.labelingInfo||[]}}q(t,l);return{labels:u(d,"binning"===n.type?"esriGeometryPolygon":a),matcher:o,fields:l,rendererOverride:f}}function k(t,i,n=!1){const s={indexCount:0,fields:{}},l="featureReduction"in t?t.featureReduction??void 0:void 0,o=l?"aggregate":"feature";if("sublayers"in t){const i={type:"subtype",subtypeField:t.subtypeField,renderers:{},symbologyType:d.DEFAULT},l={type:"subtype",mapping:{},target:"feature",subtypeField:t.subtypeField},a={type:"subtype",classes:{}},u={type:"symbol",target:"feature",aggregateFields:[],attributes:s,storage:l,mesh:{matcher:i,aggregateMatcher:null,labels:a,sortKey:null}},f=new Set;let p=0;for(const{renderer:y,subtypeCode:m,labelingInfo:g,labelsVisible:b}of t.sublayers){let t=0;"visualVariables"in y&&y.visualVariables&&(y.visualVariables.some((e=>"rotation"!==e.type))&&T.warnOnce("SubtypeGroupLayer currently only supports rotation visualVariables. All other visualVariable types will be ignored."),t=c(y.visualVariables.filter((e=>"size"!==e.type))));const u={symbologyType:d.DEFAULT,vvFlags:t,maxVVSize:0},x=$(s,o,y,u,n),v=_(s,o,y),h=b&&g;if("dictionary"===x.type)throw new e(S,"Dictionary renderer is not supported in subtype layers");if("subtype"===x.type)throw new e(S,"Nested subtype renderers is not supported");if(r(v)&&"subtype"===v.type)throw new e(S,"Nested subtype storage is not supported");if(r(v)&&r(v.attributeMapping))throw new e(S,"Non-visual-variable attributes are not supported in subtype layers");if("heatmap"===x.type)throw new e(S,"Heatmaps are not supported in subtype layers");if("pie-chart"===x.type)throw new e(S,"Pie-charts are not supported in subtype layers");if(f.has(m))throw new e(S,"Subtype codes for sublayers must be unique");f.add(m),i.renderers[m]=x,l.mapping[m]=v,h&&(a.classes[m]=h.map((e=>D(s,e,"feature",p++,u,n))))}return u}if("heatmap"===t.renderer?.type&&"raster"===g()){const{radius:e,fieldOffset:r,field:i}=t.renderer;return{type:"heatmap",aggregateFields:[],attributes:s,target:o,storage:null,mesh:{radius:e,fieldOffset:r,field:U(s,{target:o,field:i,resultType:"numeric"}).field}}}const a=P(s,t,n),f=h(t.geometryType),p=a.rendererOverride??t.renderer,y=w(p,l),m=$(s,o,p,y,n),b=_(s,o,p),x=J(s,t.orderBy,t.renderer,l),v=t.labelsVisible&&t.labelingInfo||[],E=u(v,f);let F=0;const I=[...E.map((e=>D(s,e,"feature",F++,y,n))),...a.labels.map((e=>D(s,e,"aggregate",F++,y,n)))];return{type:"symbol",target:o,attributes:s,aggregateFields:a.fields,storage:b,mesh:{matcher:m,labels:{type:"simple",classes:I},aggregateMatcher:a.matcher,sortKey:x}}}function C(e){return"heatmap"===e.renderer?.type&&"raster"===g()?{type:"heatmap"}:{type:"symbol"}}function J(t,i,n,s){if(r(s))return null;if(r(i)&&i.length){i.length>1&&T.warn(`Layer rendering currently only supports ordering by 1 orderByInfo, but found ${i.length}. All but the first will be discarded`);const r=i[0],n="ascending"===r.order?"asc":"desc";if(r.field)return{field:r.field,order:n};if(r.valueExpression){return{fieldIndex:B(t,{type:"expression",target:"feature",valueExpression:r.valueExpression,resultType:"numeric"}).fieldIndex,order:n}}return T.error(new e(S,"Expected to find a field or valueExpression for OrderByInfo",r)),null}if(r(n)&&"unique-value"===n.type&&n.orderByClassesEnabled){return{byRenderer:!0,order:"asc"}}return null}function q(e,t){const r={mesh:!0,storage:!0};for(const i of t){const{name:t,onStatisticField:n,onStatisticExpression:s,statisticType:l}=i;let o,a;const u="numeric",d="feature";if(s){a=B(e,{type:"expression",target:d,valueExpression:s.expression,resultType:u}).fieldIndex}else{o=B(e,{type:"field",target:d,field:n,resultType:u}).field}B(e,{type:"statistic",target:"aggregate",name:t,context:r,inField:o,inFieldIndex:a,statisticType:l})}}function _(e,t,r){let i;switch(r.type){case"simple":case"class-breaks":case"unique-value":case"dictionary":i={visualVariables:!0,attributes:null};break;default:i=p(r).getStorageSpec(r)}return G(e,t,i,r)}function G(e,t,i,s){if(n(i))return null;const{visualVariables:l,attributes:o}=i;let a=null;l&&"visualVariables"in s&&(a=H(e,t,s.visualVariables));const u=r(a)?4:0;let d=null;return r(o)&&(d=o.map(((r,i)=>{const{field:n,fieldIndex:s}=U(e,{valueExpression:r.valueExpression,field:r.field,resultType:"numeric",target:t});return{binding:i+u,field:n,fieldIndex:s}}))),{type:"simple",target:t,attributeMapping:d,vvMapping:a}}function H(e,t,i){if(!i||!i.length)return[];const n={storage:!0},s="numeric";return b(i).map((r=>{const i=f(r.type),{field:l,fieldIndex:o}=U(e,{target:t,valueExpression:r.valueExpression,field:r.field,context:n,resultType:s});switch(r.type){case"size":return"$view.scale"===r.valueExpression?null:{type:"size",binding:i,field:l,fieldIndex:o,normalizationField:U(e,{target:t,field:r.normalizationField,context:n,resultType:s}).field,valueRepresentation:r.valueRepresentation??null};case"color":return{type:"color",binding:i,field:l,fieldIndex:o,normalizationField:U(e,{target:t,field:r.normalizationField,context:n,resultType:s}).field};case"opacity":return{type:"opacity",binding:i,field:l,fieldIndex:o,normalizationField:U(e,{target:t,field:r.normalizationField,context:n,resultType:s}).field};case"rotation":return{type:"rotation",binding:i,field:l,fieldIndex:o}}})).filter(r)}function $(e,t,r,i,n=!1){const l=s(e,{indexCount:0,fields:{}});switch(r.type){case"simple":case"dot-density":return K(l,r,i,n);case"class-breaks":return Q(l,t,r,i,n);case"unique-value":return W(l,t,r,i,n);case"dictionary":return X(l,r,i,n);case"heatmap":return Z(l,r,i,n);case"pie-chart":return Y(l,r,i,n)}}function K(e,t,r,i=!1){const n=t.getSymbols(),s=n.length?n[0]:null;return{type:"simple",symbol:y(s,r,i),symbologyType:r.symbologyType}}function Y(e,t,r,i=!1){const n=t.getSymbols(),s=n[0],l=n.length>1?n[1]:null;return{type:"pie-chart",markerSymbol:y(s,r,i),fillSymbol:y(l,r,i),symbologyType:r.symbologyType}}function Q(e,t,r,i,n=!1){const s={mesh:!0,use:"renderer.field"},l=r.backgroundFillSymbol,{field:o,fieldIndex:a}=U(e,{target:t,field:r.field,valueExpression:r.valueExpression,resultType:"numeric",context:s}),u=r.normalizationType,d="log"===u?"esriNormalizeByLog":"percent-of-total"===u?"esriNormalizeByPercentOfTotal":"field"===u?"esriNormalizeByField":null,f=r.classBreakInfos.map((e=>({symbol:y(e.symbol,i,n),min:e.minValue,max:e.maxValue}))).sort(((e,t)=>e.min-t.min));return{type:"interval",attributes:e.fields,field:o,fieldIndex:a,backgroundFillSymbol:y(l,i,n),defaultSymbol:y(r.defaultSymbol,i,n),intervals:f,normalizationField:r.normalizationField,normalizationTotal:r.normalizationTotal,normalizationType:d,isMaxInclusive:r.isMaxInclusive,symbologyType:i.symbologyType}}function W(t,r,i,n,s=!1){const l=[],o=i.backgroundFillSymbol,a={target:r,context:{mesh:!0},resultType:"string"};if(i.field&&"string"!=typeof i.field)throw new e(S,"Expected renderer.field to be a string",i);const{field:u,fieldIndex:d}=U(t,{...a,field:i.field,valueExpression:i.valueExpression});for(const e of i.uniqueValueInfos??[])l.push({value:""+e.value,symbol:y(e.symbol,n,s)});return{type:"map",attributes:t.fields,field:u,fieldIndex:d,field2:U(t,{...a,field:i.field2}).field,field3:U(t,{...a,field:i.field3}).field,fieldDelimiter:i.fieldDelimiter??void 0,backgroundFillSymbol:y(o,n),defaultSymbol:y(i.defaultSymbol,n),map:l,symbologyType:n.symbologyType}}function X(e,t,r,i=!1){return{type:"dictionary",config:t.config,fieldMap:t.fieldMap,scaleExpression:t.scaleExpression,url:t.url,symbolOptions:r,symbologyType:r.symbologyType}}function Z(e,t,r,i=!1){const n=t.getSymbols(),s=n.length?n[0]:null;return{type:"heatmap",symbol:y(s,r,i),symbologyType:r.symbologyType}}export{q as addAggregateFields,$ as createMatcherSchema,U as createRendererAttributeSchema,I as createSchema,y as createSymbolSchema,w as createSymbolSchemaOptions};