@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
3 lines (2 loc) • 16.9 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */
import{__decorate as e}from"tslib";import t from"../../../Graphic.js";import{pickRandom as i}from"../../../core/arrayUtils.js";import s from"../../../core/Error.js";import{throwIfAborted as r}from"../../../core/promiseUtils.js";import{property as a,subclass as n}from"../../../core/accessorSupport/decorators.js";import{isHostedAgolService as o}from"../../../layers/support/arcgisLayerUrl.js";import{isTimeOnlyField as l,isNumericField as u}from"../../../layers/support/fieldUtils.js";import{generateRenderer as c}from"../../../rest/generateRenderer.js";import m from"../../../rest/support/GenerateRendererParameters.js";import h from"../../../rest/support/PivotQuery.js";import p from"../../../rest/support/StatisticDefinition.js";import d from"../../../rest/support/UniqueValueDefinition.js";import y from"../../../rest/support/UnPivotDefinition.js";import{getArcadeForPredominantCategory as f,getSQLForPredominantCategoryName as F}from"../../statistics/support/predominanceUtils.js";import{mergeWhereClauses as S,getRangeExpr as w,getSQLFilterForNormalization as g}from"../../statistics/support/utils.js";import{WorkerClient as v}from"../../statistics/support/WorkerClient.js";import{isAnyDateField as _,isIntegerField as x,castIntegerFieldToFloat as q,fieldDelimiter as V}from"../utils.js";import E from"./InMemoryLayerAdapter.js";import{getQueryParamsForExpr as b,getDataRange as z,getAttributeBinsQuery as L,processQueryAttributeBinsResult as Q,binParamsFromGenRend as T}from"./support/histogramUtils.js";import{ensureFeaturesJSON as j,getSummaryStatsQuery as N,getSummaryStatisticsFromFeatureSet as B,getSummaryStatsQueryForFields as M,getSummaryStatsPivotQuery as $,getUVQuery as O,getUniqueValuesFromFeatureSet as C,defaultNumBins as P,updateQueryWithFeatureFilter as R,getHistogramFromFeatureSet as I,getFieldExpr as A,getDomainsForFields as k,getBins as U,getPredominantCategoriesFromUVInfos as D,getMissingFields as G}from"./support/utils.js";import{processSummaryStatisticsResult as W,createUVResult as J,getEqualIntervalBins as H,createClassBreaksDefinition as Z,resolveCBResult as K}from"../../../statistics/utils.js";import{getScaleToResolutionFactor as X}from"../../../views/2d/viewpointUtils.js";const Y=5,ee=2e4,te=4e5;let ie=class extends E{constructor(){super(...arguments),this.adapterName="feature-layer-adapter"}_isStatsSupportedOnService(){const e=this.layer;if(!e.capabilities?.query?.supportsStatistics||"multipatch"===this.geometryType&&!o(e.url)&&e.version<10.5)throw new s(`${this.adapterName}:not-supported`,"Layer does not support statistics query");return Promise.resolve()}_fetchFeaturesFromService(e,t){return this.layer.queryFeatures(e,{signal:t}).then(e=>e.features)}_fetchFeaturesJSONFromService(e,t){return this._fetchFeaturesFromService(e,t).then(j)}_summaryStatsFromGenRend(e){const t=e.normalizationType,i=e.normalizationField;return this.classBreaks({field:e.field,numClasses:Y,classificationMethod:"standard-deviation",standardDeviationInterval:.25,normalizationType:t,normalizationField:"field"===t?i:void 0,minValue:e.minValue,maxValue:e.maxValue,filter:e.filter,signal:e.signal}).then(t=>{let i,s,r;if(t.classBreakInfos?.some(e=>(e.hasAvg&&(i=e),!!i)),i){const e=i.maxValue-i.minValue;s=i.minValue+e/2,r=4*e}const a={min:t.minValue,max:t.maxValue,avg:s,stddev:r};return W(a,e.outStatisticTypes)})}async _summaryStatsFromServiceQuery(e,t){await this._isStatsSupportedOnService(),"percent-of-total"===e.normalizationType&&(e.normalizationTotal=await this._getNormalizationTotal(e.field,e.normalizationType,e.filter));const i=_(t)||l(t),s="capabilities"in this.layer?this.layer.capabilities:null,r=N(this,e,t,s?.query?.supportsPercentileStatistics??!1),a=await this.layer.queryFeatures(r,{signal:e.signal}),n=B(a,i);return W(n,e.outStatisticTypes)}async _summaryStatsForFieldsBasic(e){const{outStatisticTypes:t,fields:i}=e,s=50,r=[];for(let o=0;o<i.length;o+=s){const t=i.slice(o,o+s),a=M(this,e,t);r.push(this.layer.queryFeatures(a,{signal:e.signal}))}const a=(await Promise.all(r)).flatMap(e=>e.features).map(e=>e.attributes).reduce((e,t)=>Object.assign(e,t),{}),n={};for(const o in a){const e=o.match(/^(\w+)_value_/);if(null==a[o]||!e)continue;switch(e[1]){case"min":n.min=null==n.min?a[o]:Math.min(n.min,a[o]);break;case"max":n.max=null==n.max?a[o]:Math.max(n.max,a[o]);break;case"sum":n.sum=(n.sum||0)+a[o];break;case"count":n.count=(n.count||0)+a[o]}}return W(n,t)}async _summaryStatsForFieldsAdvanced(e,t){const{outStatisticTypes:i,fields:s}=e,r=i?.exclude?.includes("variance")||i?.include&&!i.include.includes("variance"),a=i?.exclude?.includes("stddev")||i?.include&&!i.include.includes("stddev");if(null==t.sum||!t.count||r&&a)return t;t.avg=t.sum/t.count;const n=50,o=[];for(let u=0;u<s.length;u+=n){const i=s.slice(u,u+n),r=M(this,e,i);r.outStatistics=[];for(const e of i){const i=`sumOfSquares_${e}`,s=`(power(${x(this.layer,e)?q(e):e} - ${t.avg}, 2))`,a=new p({statisticType:"sum",onStatisticField:s,outStatisticFieldName:i});r.outStatistics.push(a)}o.push(this.layer.queryFeatures(r,{signal:e.signal}))}const l=(await Promise.all(o)).reduce((e,t)=>e+Object.values(t.features[0].attributes).reduce((e,t)=>e+t,0),0);return t.variance=l/(t.count-1),t.stddev=Math.sqrt(t.variance),W(t,i)}async _summaryStatsForFields(e){const t=await this._summaryStatsForFieldsBasic(e);return this._summaryStatsForFieldsAdvanced(e,t)}async _summaryStatsUsingQueryPivot(e){await this._isStatsSupportedOnService();const t="capabilities"in this.layer?this.layer.capabilities:null,i=$(this,e,t?.query?.supportsPercentileStatistics??!1),s=await this.layer.queryPivot(i,{signal:e.signal}),r=B(s,!1);return W(r,e.outStatisticTypes)}_uvFromGenRenderer(e,t){const i=e.field??void 0,s=new d({attributeField:i}),r=new m({classificationDefinition:s});return this.generateRenderer(r,e.signal).then(e=>{const t={},s=this.getField(i);return e.uniqueValues.forEach(e=>{let i=e.value;null!=i&&""!==i&&("string"!=typeof i||""!==i.trim()&&"<null>"!==i.toLowerCase())||(i=null),null==t[i]?t[i]={count:e.count,data:u(s)&&i?Number(i):i}:t[i].count=t[i].count+e.count}),{count:t}}).then(i=>J(i,[t],e.returnAllCodedValues))}async _uvFromServiceQuery(e,t){return this._isStatsSupportedOnService().then(()=>this.layer.queryFeatures(O(this,e),{signal:e.signal})).then(t=>C(t,{layer:this,field:e.field,field2:e.field2,field3:e.field3,fieldDelimiter:V,view:e.view,signal:e.signal})).then(i=>J(i,t,e.returnAllCodedValues,V))}_getNormalizationTotal(e,t,i,s){return e&&"percent-of-total"===t?this.summaryStatistics({field:e,outStatisticTypes:{include:["sum"]},filter:i,signal:s}).then(e=>e.sum):Promise.resolve(null)}_histogramForExpr(e){return this._getNormalizationTotal(e.field,e.normalizationType,e.filter,e.signal).then(t=>{const i=b(e,this,t);return z(i,this,e.minValue,e.maxValue).then(s=>{const r=s.min,a=s.max;if(null==r||null==a)return{bins:[],minValue:r,maxValue:a,normalizationTotal:t};const n=e.numBins||P,o=H(r,a,n),l=se(i.sqlExpression,o,null!=e.minValue&&null!=e.maxValue),u=new p({statisticType:"count",outStatisticFieldName:"countOFExpr",onStatisticField:"1"}),c=this.layer.createQuery();return c.where=S(c.where,i.sqlWhere),c.sqlFormat="standard",c.outStatistics=[u],c.groupByFieldsForStatistics=[l],c.orderByFields=[l],R(c,e.filter),this._isStatsSupportedOnService().then(()=>this.layer.queryFeatures(c,{signal:i.signal})).then(e=>I(e,r,a,n,t))})})}async _histogramForFields(e){const{min:t,max:i}=await z({fields:e.fields,sqlWhere:e.sqlWhere,filter:e.filter,signal:e.signal},this,e.minValue,e.maxValue);if(null==t||null==i)return{bins:[],minValue:t,maxValue:i};const s="newField",r=e.numBins||P,a=se(s,H(t,i,r),null!=e.minValue&&null!=e.maxValue),n=new p({statisticType:"count",outStatisticFieldName:"countOFExpr",onStatisticField:s}),o=new h,{where:l,timeExtent:u}=this.createQuery();return o.where=S(l,e.sqlWhere),o.outPivots=[new y({sourceFields:e.fields,valueFieldName:s})],o.outStatistics=[n],o.groupByFieldsForStatistics=[a],o.orderByFields=[a],o.timeExtent=u,R(o,e.filter),this._isStatsSupportedOnService().then(()=>this.layer.queryPivot(o,{signal:e.signal})).then(e=>I(e,t,i,r))}async _histogramFromQueryAttributeBins(e){const{field:t,normalizationType:i,filter:s,signal:r}=e,a=await this._getNormalizationTotal(t,i,s,r),{query:n,min:o,max:l}=await L(e,this,a,this.createQuery());if(!n)return{bins:[],minValue:o,maxValue:l,normalizationTotal:a};const u=await this.layer.queryAttributeBins(n,{signal:r});return Q(u,t?this.getField(t):null,{minValue:o,maxValue:l,normalizationTotal:a})}_classBreaksFromGenRend(e){const{field:t,normalizationType:i,normalizationField:s,normalizationTotal:r,signal:a}=e,n=g({field:t,normalizationType:i,normalizationField:s}),o=A({field:t,normalizationType:i,normalizationField:s,normalizationTotal:r,layer:this}),l=w(o,e.minValue,e.maxValue),u=Z({field:t,normalizationType:i,normalizationField:s,classificationMethod:e.classificationMethod,standardDeviationInterval:e.standardDeviationInterval,breakCount:e.numClasses||Y}),c=new m({classificationDefinition:u});return c.where=S(n,l),this.generateRenderer(c,a).then(t=>K(t,e.classificationMethod))}async summaryStatistics(e){const{field:t,fields:i,normalizationType:a,valueExpression:n,sqlExpression:o,view:u,features:c,useFeaturesInView:m}=e,h=t?this.getField(t):null,p=_(h)||l(h),d=n&&!(o&&this.supportsSQLExpression),y=this._hasLocalSource||c||m,f="3d"===u?.type;if(i?.length){const t={...e,fields:i};if(!this.layer.capabilities?.operations?.supportsQueryPivot)return await this._summaryStatsForFields(t);try{return await this._summaryStatsUsingQueryPivot(t)}catch{return await this._summaryStatsForFields(t)}}if(y||d)return d||c||m||f||this._hasLocalSource&&!this.layer.capabilities.query.supportsStatistics?this._summaryStatsFromMemory(e,h):this._summaryStatsFromClientQuery(e,h);if(!this.supportsSQLExpression&&(p||o||"natural-log"===a||"square-root"===a))throw new s(`${this.adapterName}:not-supported`,"Layer does not support standardized SQL expression for queries");return(a&&!this.supportsSQLExpression?this._summaryStatsFromGenRend(e):this._summaryStatsFromServiceQuery(e,h)).catch(()=>(r(e.signal),this._summaryStatsFromMemory(e,h)))}async uniqueValues(e){const{valueExpression:t,sqlExpression:i,features:s,useFeaturesInView:a,signal:n}=e,o=t&&!(i&&this.supportsSQLExpression),l=this._hasLocalSource||s||a||o,u=e.view,c="3d"===u?.type,m=await k(e,this);return l?o||s||a||c||this._hasLocalSource&&!this.layer.capabilities.query.supportsStatistics?this._uvFromMemory(e,m):this._uvFromClientQuery(e,m):this._uvFromServiceQuery(e,m).catch(t=>(r(n),!e.field||e.field2||e.field3||e.filter?t:this._uvFromGenRenderer(e,m[0]))).catch(()=>(r(n),c?this._uvFromMemory(e,m):this._uvFromClientQuery(e,m)))}async histogram(e){const{field:t,normalizationType:i,normalizationField:a,classificationMethod:n,view:o,filter:u,signal:c}=e,m=t?this.getField(t):null,h=_(m)||l(m),p=e.valueExpression||e.sqlExpression,d=e.valueExpression&&!(e.sqlExpression&&this.supportsSQLExpression),y=this._hasLocalSource||e.features||e.useFeaturesInView||d,f=this.supportsSQLExpression,F=!n||"equal-interval"===n,S=e.minValue,g=e.maxValue,v=null!=S&&null!=g,x=e.numBins||P;if(e.fields?.length){if(!f)throw new s(`${this.adapterName}:not-supported`,"Layer does not support standardized SQL expression for queries");if(!this.layer.capabilities?.operations?.supportsQueryPivot)throw new s(`${this.adapterName}:not-supported`,"Layer does not support pivot queries");return this._histogramForFields(e)}if(this.layer.capabilities?.operations?.supportsQueryBins&&e.useQueryAttributeBins&&!d){if(y)return this._histogramFromQueryAttributeBinsFromMemory(e);try{return await this._histogramFromQueryAttributeBins(e)}catch{return r(c),this._histogramFromQueryAttributeBinsFromMemory(e)}}if(y)return this._histogramFromMemory(e);if((p||f)&&F){if(!f&&(p||"natural-log"===i||"square-root"===i))throw new s(`${this.adapterName}:not-supported`,"Layer does not support standardized SQL expression for queries");return this._histogramForExpr(e)}if(h&&F)throw new s(`${this.adapterName}:not-supported`,"Normalization and date field are not allowed when layer does not support standardized SQL expression for queries");return i||!F?T(e,this).then(r=>{if(!v)return U(this,r,t,x,o,u,c);if(S>r.max||g<r.min)throw new s(`${this.adapterName}:insufficient-data`,"Range defined by 'minValue' and 'maxValue' does not intersect available data range of the field");if(F)return U(this,{min:S,max:g,sqlExpr:r.sqlExpr,excludeZerosExpr:r.excludeZerosExpr},t,x,o,u,c);{const s={field:t,normalizationType:i,normalizationField:a,normalizationTotal:r.normTotal,layer:this},n=A(s),l=w(n,S,g);return T(e,this,l).then(e=>U(this,e,t,x,o,u,c))}}):this._histogramForField(e)}async classBreaks(e){const t=!1!==e.analyzeData,i=this._hasLocalSource||e.features||e.useFeaturesInView||e.valueExpression||e.filter;if(t&&i)return this._classBreaksFromMemory(e);return(t?this._classBreaksFromGenRend(e):this._classBreaksFromInterpolation(e)).catch(()=>(r(e.signal),this._classBreaksFromMemory(e)))}async queryFeatureCount(e){if(this._hasLocalSource)throw new s(`${this.adapterName}:not-supported`,"Layer does not support count query");const t=this.layer,i=t.createQuery();return i.where=S(i.where,e.whereClause),R(i,e.filter),t.queryFeatureCount(i,{signal:e.signal})}async generateRenderer(e,t){const i=this.layer;if(this._hasLocalSource||i.version<10.1)throw new s(`${this.adapterName}:not-supported`,"Layer does not support generateRenderer operation (requires ArcGIS Server version 10.1+)");const r=i.createQuery();return e.where=S(e.where,r.where),c(i.parsedUrl?.path??"",{source:i.dynamicDataSource??void 0,gdbVersion:i.gdbVersion??void 0},e,{signal:t})}async predominantCategories(e){if(!this._hasLocalSource&&!this.supportsSQLExpression)throw new s(`${this.adapterName}:not-supported`,"Layer does not support advanced SQL expressions and standardized queries");const{fields:t,view:i,signal:r,filter:a}=e,n=f(t),o=F(t),l=i&&this._hasLocalSource?await this._uvFromMemory({valueExpression:n,view:i,signal:r,filter:a}):await this._uvFromServiceQuery({sqlExpression:o.expression,valueExpression:n,signal:r,filter:a});return D(l.uniqueValueInfos,t)}async getSampleFeatures(e,s){const{view:a,requiredFields:n,returnGeometry:o,sqlWhere:l,filter:u,signal:c}=e,m=e.sampleSize;if(null==m||0===m)return[];const h=this.layer.createQuery(),p=1,d="json"===s;h.outSpatialReference=a?.spatialReference,h.returnGeometry=!!o,h.outFields=n,h.where=S(h.where,l),R(h,u);let y=[],f=!1;if(a)try{const r=await a.whenLayerView(this.layer);if(f=!G(this,n,r).length,f){if(m>=1&&!e.filter&&"getSampleFeatures"in r){await this._waitForLayerViewUpdate(r);const e=await r.getSampleFeatures({minFeatureCount:m,sampleSize:m});if(null!=e)return d?e:e.map(e=>t.fromJSON(e))}if(y=await this._fetchFeaturesFromMemory(r,h,c,s),y.length>=m&&m>0)return i(y,m,p)}}catch(F){r(c)}try{if(this._hasLocalSource)return f?y:d?await this._fetchFeaturesJSONFromService(h,c):await this._fetchFeaturesFromService(h,c);const t=await this.queryFeatureCount({view:a,filter:u,signal:c}),s=this.layer.capabilities.query.maxRecordCount;let r=-1===m?t:m;if(r=s&&r>s?s:r,t<=y.length||y.length>=s)return y;if(h.maxAllowableOffset=e.resolution||(a?a.extent.width/a.width/a.scale:X(this.layer.spatialReference))*te,t<=r)return d?await this._fetchFeaturesJSONFromService(h,c):await this._fetchFeaturesFromService(h,c);if(t<=ee){const e=this.layer.createQuery();R(e,u);const t=await this.layer.queryObjectIds();return h.objectIds=i(t,r,p),d?await this._fetchFeaturesJSONFromService(h,c):await this._fetchFeaturesFromService(h,c)}return this.layer.capabilities?.query?.supportsPagination&&(h.num=Math.min(r,ee)),d?await this._fetchFeaturesJSONFromService(h,c):await this._fetchFeaturesFromService(h,c)}catch(F){return r(c),y}}load(e){const t=this.layer.load(e).then(async t=>{this.geometryType=t.geometryType,this.objectIdField=t.objectIdField,this.supportsSQLExpression=t.capabilities?.query?.supportsSqlExpression,this._hasLocalSource="parquet"===t.type||!t.url&&!!t.source,this.hasQueryEngine=this._hasLocalSource,this.minScale=t.minScale,this.maxScale=t.maxScale,this.fullExtent=t.fullExtent,this.workerClient=v.getInstance(),await this.workerClient.open(e.signal)});return this.addResolvingPromise(t),Promise.resolve(this)}};function se(e,t,i){const s=[],r=t.length;return t.forEach((t,a)=>{const[n,o]=t;let l=null;l=0!==a||i?a!==r-1||i?S(`${e} >= ${n}`,`${e} ${a===r-1?" <= ":" < "} ${o}`):`${e} >= ${n}`:`${e} < ${o}`,s.push("WHEN ("+l+") THEN "+(a+1))}),["CASE",s.join(" "),"ELSE 0","END"].join(" ")}e([a({readOnly:!0})],ie.prototype,"adapterName",void 0),e([a({constructOnly:!0})],ie.prototype,"layer",void 0),ie=e([n("esri.smartMapping.support.adapters.FeatureLayerAdapter")],ie);export{ie as default};