@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
3 lines (2 loc) • 9.57 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */
import{neverAbortedSignal as e}from"../../arcadeEnvironment.js";import{StringEnum as t}from"../../enum.js";import{a3 as s}from"../../../chunks/languageUtils.js";import{SqlExpressionAdapted as i,OriginalField as r,AdaptedFeatureSet as o}from"./Adapted.js";import a from"./AttributeFilter.js";import n from"./OrderBy.js";import{FeatureSetError as l,throwIfCancelled as d}from"../support/errorsupport.js";import{FeatureSet as u,emptyFeaturesResult as p}from"../support/FeatureSet.js";import f from"../support/OrderbyClause.js";import{isSingleField as c,toWhereClause as h,predictType as g,scanForField as m,reformulateWithoutField as _}from"../support/sqlUtils.js";import y from"../support/StatsField.js";import{createMD5Hash as F,outputTypes as w}from"../../../core/MD5.js";import{aggregateFunction as b}from"../../../core/sql/AggregateFunctions.js";import{DateOnly as S}from"../../../core/sql/DateOnly.js";import{SqlTimeStampOffset as A}from"../../../core/sql/SqlTimestampOffset.js";import{TimeOnly as x}from"../../../core/sql/TimeOnly.js";import I from"../../../core/sql/WhereClause.js";import G from"../../../layers/support/Field.js";const B=new t(["MIN","MAX","VAR","STDDEV","COUNT","SUM","AVG"],[["VARIANCE","VAR"],["AVERAGE","AVG"],["MEAN","AVG"],["STDEV","STDDEV"]]);class j extends u{constructor(e){super(),this.declaredClass="esri.arcade.featureset.actions.Aggregate",this._decodedStatsFields=[],this._decodedGroupByFields=[],this._canDoSimpleGroupBy=!0,this._physicalGroupByFields=[],this.objectIdField="ROW__ID",this._adaptedFields=[],this._uniqueIds=1,this._maxQuery=10,this._maxProcessing=10,this._parent=e.parentfeatureset,this._config=e}isTable(){return!0}_nextUniqueName(e){for(;1===e["T"+this._uniqueIds.toString()];)this._uniqueIds++;const t="T"+this._uniqueIds.toString();return e[t]=1,t}_convertToEsriFieldType(e){return e}_initialiseFeatureSet(){const e=this._parent.getFieldsIndex();this.objectIdField="ROW__ID",this.globalIdField="";let t=!1,s=1;for(;!1===t;){let e=!1;for(const t of this._config.groupbyfields)if(t.name.toLowerCase()===this.objectIdField.toLowerCase()){e=!0;break}if(!1===e)for(const t of this._config.statsfields)if(t.name.toLowerCase()===this.objectIdField.toLowerCase()){e=!0;break}!1===e?t=!0:(this.objectIdField="ROW__ID"+s.toString(),s++)}for(const i of this._config.statsfields){const t=new y;t.field=i.name,t.tofieldname=i.name,t.workingexpr=i.expression instanceof I?i.expression:I.create(i.expression,{fieldsIndex:e,timeZone:this.dateFieldsTimeZoneDefaultUTC}),t.typeofstat=B.lookup(i.statistic)??"COUNT",this._decodedStatsFields.push(t)}this._decodedGroupByFields=[];for(const i of this._config.groupbyfields){const t={name:i.name,singlefield:null,tofieldname:i.name,expression:i.expression instanceof I?i.expression:I.create(i.expression,{fieldsIndex:e,timeZone:this.dateFieldsTimeZoneDefaultUTC}),sqlType:null};this._decodedGroupByFields.push(t)}const o={};this.geometryType=this._parent.geometryType,this.spatialReference=this._parent.spatialReference,this.hasM=this._parent.hasM,this.hasZ=this._parent.hasZ,this.typeIdField="";for(const i of this._parent.fields)o[i.name.toUpperCase()]=1;this.types=null,this.subtypes=null,this.subtypeField="",this.fields=[];const a=new y;a.field=this._nextUniqueName(o),a.tofieldname=this.objectIdField,a.workingexpr=I.create(this._parent.objectIdField,{fieldsIndex:this._parent.getFieldsIndex(),timeZone:this.dateFieldsTimeZoneDefaultUTC}),a.typeofstat="MIN",this._decodedStatsFields.push(a);for(const r of this._decodedGroupByFields){const e=new G;if(r.name=this._nextUniqueName(o),e.name=r.tofieldname,e.alias=e.name,c(r.expression)){const t=this._parent.getField(h(r.expression,0));if(!t)throw new l("AggregationFieldNotFound");r.name=t.name,r.singlefield=t.name,this._physicalGroupByFields.push(t.name),e.type=t.type,r.sqlType=t.type}else{e.type=this._convertToEsriFieldType(g(r.expression,this._parent.fields));const t=new G;t.name=r.name,t.alias=t.name,this._physicalGroupByFields.push(r.name),this._adaptedFields.push(new i(t,r.expression)),this._canDoSimpleGroupBy=!1,r.sqlType=e.type}this.fields.push(e)}if(this._adaptedFields.length>0)for(const i of this._parent.fields)this._adaptedFields.push(new r(i));for(const i of this._decodedStatsFields){const e=new G;let t=null;i.field=this._nextUniqueName(o),e.name=i.tofieldname,e.alias=e.name;const s=null!==i.workingexpr&&c(i.workingexpr)?h(i.workingexpr,0):"";switch(i.typeofstat){case"SUM":if(""!==s){if(t=this._parent.getField(s),!t)throw new l("AggregationFieldNotFound");e.type=t.type}else e.type="double";break;case"MIN":case"MAX":if(""!==s){if(t=this._parent.getField(s),!t)throw new l("AggregationFieldNotFound");e.type=t.type}else e.type="double";break;case"COUNT":e.type="integer";break;case"STDDEV":case"VAR":case"AVG":if(""!==s&&(t=this._parent.getField(s),!t))throw new l("AggregationFieldNotFound");e.type="double"}this.fields.push(e)}}async _queryAll(){return(await this.query({abortSignal:e})).features}async query(e){if(null!=e.spatialFilter)return p;const t={ordered:!1,nowhereclause:!1};await this._ensureLoaded();let s=e.where;if(null!=s)for(const o of this._decodedStatsFields)if(!0===m(s,o.tofieldname)){t.nowhereclause=!0,s=null;break}let i=e.orderBy;if(null!=i){t.ordered=!0;for(const e of this._decodedStatsFields)if(!0===i.scanForField(e.tofieldname)){i=null,t.ordered=!1;break}if(null!==i)for(const e of this._decodedGroupByFields)if(null===e.singlefield&&!0===i.scanForField(e.tofieldname)){i=null,t.ordered=!1;break}}if(!1!==this._canDoSimpleGroupBy&&await this._parent.canQueryAggregate({groupBy:this._physicalGroupByFields,statistics:this._decodedStatsFields,where:null,spatialFilter:null,abortSignal:e.abortSignal})){const r=await this._parent.queryAggregate({groupBy:this._physicalGroupByFields,statistics:this._decodedStatsFields,where:s?this._reformulateWhereClauseWithoutGroupByFields(s):null,spatialFilter:null,orderBy:i?this._reformulateOrderClauseWithoutGroupByFields(i):null,abortSignal:e.abortSignal});return d(e.abortSignal),{...r,filterApplied:!t.nowhereclause&&r.filterApplied,ordered:!0===t.ordered&&r.ordered,features:this._fixAggregateAttributeNames(r.features)}}const r=this._adaptedFields.length>0?new o({parentfeatureset:this._parent,adaptedFields:this._adaptedFields,extraFilter:null}):this._parent;if(!0===t.nowhereclause){const t=new n({parentfeatureset:r,orderbyclause:new f(this._physicalGroupByFields.join(",")+","+this._parent.objectIdField+" ASC")});return{filterApplied:!1,spatialFilterApplied:!1,ordered:!1,features:this._aggregateSortedFeatureGroups((await t.query({abortSignal:e.abortSignal})).features,this._maxQuery,e.abortSignal)}}let l=r;null!=s&&(l=new a({parentfeatureset:l,whereclause:this._reformulateWhereClauseWithoutGroupByFields(s)}));const u=new n({parentfeatureset:l,orderbyclause:new f(this._physicalGroupByFields.join(",")+","+this._parent.objectIdField+" ASC")});return{filterApplied:!1,spatialFilterApplied:!1,ordered:!1,features:this._aggregateSortedFeatureGroups((await u.query({abortSignal:e.abortSignal})).features,this._maxQuery,e.abortSignal)}}async*_fixAggregateAttributeNames(e){for await(const t of e)yield t.map(e=>{const t={geometry:e.geometry,attributes:{}},s={};for(const i in e.attributes)s[i.toLowerCase()]=e.attributes[i];for(const i of this._decodedGroupByFields)t.attributes[i.tofieldname]=s[i.name.toLowerCase()];for(const i of this._decodedStatsFields)t.attributes[i.tofieldname]=s[i.field.toLowerCase()];return t})}async*_aggregateSortedFeatureGroups(e,t,i){let r=null,o=[];for await(const a of e){await s(),d(i);for(const e of a){const t=this._generateAggregateHash(e);null==r?r={features:[e],id:t}:t!==r.id?(o.push(this._calculateAndAppendAggregateItem(r)),r={features:[e],id:t}):r.features.push(e)}o.length>=t&&(yield o,o=[])}null!=r&&(o.push(this._calculateAndAppendAggregateItem(r)),yield o)}async queryStat(e){return{calculated:!1}}async canQueryAggregate(e){return!1}async queryAggregate(e){throw new l("NeverReach")}_reformulateWhereClauseWithoutStatsFields(e){for(const t of this._decodedStatsFields)e=_(e,t.tofieldname,h(t.workingexpr,0),this._parent.getFieldsIndex());return e}_reformulateWhereClauseWithoutGroupByFields(e){for(const t of this._decodedGroupByFields)t.tofieldname!==t.name&&(e=_(e,t.tofieldname,h(t.expression,0),this._parent.getFieldsIndex()));return e}_reformulateOrderClauseWithoutGroupByFields(e){const t=[];for(const s of this._decodedGroupByFields)s.tofieldname!==s.name&&t.push({field:s.tofieldname,newfield:s.name});return t.length>0?e.replaceFields(t):e}_calculateFieldStat(e,t,s){const i=[];for(const r of e.features)if(null!==t.workingexpr){const e=t.workingexpr.calculateValue(r);null!==e&&(e instanceof S||e instanceof x?i.push(e.toNumber()):e instanceof A?i.push(e.toMilliseconds()):i.push(e))}else i.push(null);s.attributes[t.tofieldname]=b(t.typeofstat,[i])}_calculateAndAppendAggregateItem(e){const t={attributes:{}};for(const s of this._decodedGroupByFields){const i=s.singlefield?e.features[0].attributes[s.singlefield]:I.convertValueToStorageFormat(s.expression.calculateValue(e.features[0]),s.sqlType);t.attributes[s.tofieldname]=i}for(const s of this._decodedStatsFields)this._calculateFieldStat(e,s,t);return t}_generateAggregateHash(e){let t="";for(const s of this._decodedGroupByFields){const i=s.singlefield?e.attributes[s.singlefield]:s.expression.calculateValue(e);t+=null==i?":":":"+i.toString()}return F(t,w.String)}async getFeatureByObjectId(){throw new l("NotImplemented")}}export{j as default};