UNPKG

@arcgis/core

Version:

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

3 lines (2 loc) • 18 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */ import{id as e}from"../../../kernel.js";import t from"../../../request.js";import{neverAbortedSignal as r}from"../../arcadeEnvironment.js";import i from"../../Attachment.js";import a from"../../Dictionary.js";import{throwIfCancelled as s,FeatureSetError as l}from"../support/errorsupport.js";import{RootFeatureSet as n,emptyFeaturesResult as o,assignSpatialReferenceOnFeatures as u}from"../support/FeatureSet.js";import{defaultMaxRecords as c,stableStringify as h,extractServiceUrl as y}from"../support/shared.js";import{toWhereClause as d,isSingleField as p}from"../support/sqlUtils.js";import{decodeStatType as _}from"../support/stats.js";import{sliceEquals as m}from"../../../core/arrayUtils.js";import{createMD5Hash as f,outputTypes as F}from"../../../core/MD5.js";import{sqlAnd as w}from"../../../core/sql.js";import S from"../../../core/sql/WhereClause.js";import g from"../../../layers/FeatureLayer.js";import{toQueryStringParameters as b}from"../../../rest/query/operations/queryRelatedRecords.js";import R from"../../../rest/support/AttachmentQuery.js";import I from"../../../rest/support/Query.js";import q from"../../../rest/support/StatisticDefinition.js";function T(e){if(0===e.length)throw new l("NeverReach");const t=[];for(let i=0;i<e.length;i++){const r=e[i],a=[`"${r.name.replaceAll('"','""')}" ${r.asc?">":"<"} @last_${i}`];for(let t=0;t<i;t++){const r=e[t];a.push(`"${r.name.replaceAll('"','""')}" = @last_${t}`)}t.push(a.join(" AND "))}const r=t.join(" OR ");return S.create(r)}function Q(e,t){null==e.clause&&(e.clause=T(e.keyFields));for(let r=0;r<e.keyFields.length;r++){const i=e.keyFields[r].name;e.clause.parameters[`last_${r}`]=t.attributes[i]}}class v extends n{constructor(e){super(),this.declaredClass="esri.arcade.featureset.sources.FeatureLayerDynamic",this._removeGeometry=!1,this._overrideFields=null,this._requestStandardised=!1,this._useDefinitionExpression=!0,this._recentlyUsedQueries=null,this._featureSetQueryInterceptor=null,this._featureSetInfo=null,this._maxProcessing=1e3,this._layer=e.layer,e.spatialReference&&(this.spatialReference=e.spatialReference),void 0!==e.outFields&&(this._overrideFields=e.outFields),void 0!==e.includeGeometry&&(this._removeGeometry=!1===e.includeGeometry),e.lrucache&&(this._recentlyUsedQueries=e.lrucache),e.interceptor&&(this._featureSetQueryInterceptor=e.interceptor)}_maxQueryRate(){return c}get urlQueryPath(){return this._layer.parsedUrl.path||""}convertQueryToLruCacheKey(e){const t=this.urlQueryPath+","+h(e.toJSON());return f(t,F.String)}async loadImpl(){return!0===this._layer.loaded?(this._initialiseFeatureSet(),this):(await this._layer.load(),this._initialiseFeatureSet(),this)}_initialiseFeatureSet(){if(this.spatialReference??=this._layer.spatialReference,this.geometryType=this._layer.geometryType??"",this.fields=this._layer.fields.slice(),this.hasZ=!0===this._layer.capabilities?.data?.supportsZ,this.hasM=!0===this._layer.capabilities?.data?.supportsM,null!==this._overrideFields)if(1===this._overrideFields.length&&"*"===this._overrideFields[0])this._overrideFields=null;else{const e=new Set(this._overrideFields.map(e=>e.toLowerCase()));this.fields=this.fields.filter(({type:t,name:r})=>"oid"===t||e.has(r.toLowerCase())),this._overrideFields=this.fields.map(({name:e})=>e)}if(this._layer.source&&this._layer.source.sourceJSON){const e=this._layer.source.sourceJSON.currentVersion;!0===this._layer.source.sourceJSON.useStandardizedQueries?(this._databaseType=1,null!=e&&e>=10.61&&(this._databaseType=0)):null!=e&&(e>=10.5&&(this._databaseType=1,this._requestStandardised=!0),e>=10.61&&(this._databaseType=0))}this.objectIdField=this._layer.objectIdField;for(const e of this.fields)"global-id"===e.type&&(this.globalIdField=e.name);this.subtypeField=this._layer.subtypeField??"",this.subtypes=this._layer.subtypes,this.typeIdField=("typeIdField"in this._layer?this._layer.typeIdField:null)??"",this.types="types"in this._layer?this._layer.types:null}async _runDatabaseProbe(e){await this._ensureLoaded();const t=new I;this.datesInUnknownTimezone&&(t.timeReferenceUnknownClient=!0),t.where=e.replace("OBJECTID",this._layer.objectIdField);try{return await this._layer.queryObjectIds(t),!0}catch{return!1}}_canUsePagination(){return!(!this._layer.capabilities||!this._layer.capabilities.query||!0!==this._layer.capabilities.query.supportsPagination)}_cacheableFeatureSetSourceKey(){return this._layer.url}get gdbVersion(){return this._layer&&this._layer.capabilities&&this._layer.capabilities.data&&this._layer.capabilities.data.isVersioned?this._layer.gdbVersion||"SDE.DEFAULT":""}nativeCapabilities(){return{title:this._layer.title??"",source:this,canQueryRelated:!0,capabilities:this._layer.capabilities,databaseType:this._databaseType,requestStandardised:this._requestStandardised}}async _queryAll(){return(await this.query({abortSignal:r})).features}async query(e){return await this._ensureLoaded(),this.isTable()&&null!=e.spatialFilter?o:this._canUsePagination()?this._queryUsingPaging(e):this._queryUsingIdSetTraversal(e)}async _queryUsingPaging(e){let t="",r=!1;null!=e.orderBy&&!0===this._layer.capabilities?.query?.supportsOrderBy&&(t=e.orderBy.constructClause(),r=!0);const i=await this.databaseType(),a=null==e.where?null==e.spatialFilter?"1=1":"":d(e.where,i);let s=this._maxQueryRate();const l=this._layer.capabilities?.query.maxRecordCount;null!=l&&l<s&&(s=l);const n=!0!==this._removeGeometry,o=this._overrideFields??this._fieldsIncludingObjectId(["*"]),u=this._createQuery();return u.where=w(u.where,a),null!=e.spatialFilter&&(u.spatialRelationship=this._makeRelationshipEnum(e.spatialFilter.relation),u.relationParameter=this._makeRelationshipParam(e.spatialFilter.relation),u.geometry=e.spatialFilter.geometry),u.orderByFields=""!==t?t.split(","):null,u.outFields=o,u.returnGeometry=n,u.outSpatialReference=this.spatialReference,{ordered:r,filterApplied:!0,spatialFilterApplied:!0,features:this._queryPaginated(u,s,e.abortSignal)}}async*_queryPaginated(e,t,r){let i;e.num=t,e.start=0;do{s(r),i=await this.executeQuery(e,"execute"),yield i.features,e.start+=t}while(!0===i.exceededTransferLimit)}async _queryUsingIdSetTraversal(e){let t="",r=!1;null!=e.orderBy&&this._layer.capabilities&&this._layer.capabilities.query&&!0===this._layer.capabilities.query.supportsOrderBy&&(t=e.orderBy.constructClause(),r=!0);const i=await this.databaseType(),a=null==e.where?null==e.spatialFilter?"1=1":"":d(e.where,i),l=this._createQuery();l.where=w(l.where,a),null!=e.spatialFilter&&(l.spatialRelationship=this._makeRelationshipEnum(e.spatialFilter.relation),l.relationParameter=this._makeRelationshipParam(e.spatialFilter.relation),l.geometry=e.spatialFilter.geometry),l.orderByFields=""!==t?t.split(","):null,l.outSpatialReference=this.spatialReference;const n=await this.executeQuery(l,"executeForIds");if(s(e.abortSignal),null==n||n.length<=0)return o;let u=this._maxQueryRate();const c=this._layer.capabilities?.query.maxRecordCount;null!=c&&c<u&&(u=c);const h=this._createQuery();return l.outFields=this._overrideFields??this._fieldsIncludingObjectId(["*"]),l.returnGeometry=!0!==this._removeGeometry,l.outSpatialReference=this.spatialReference,{ordered:r,filterApplied:!0,spatialFilterApplied:!0,features:this._traverseIdSet(h,n,u,e.abortSignal)}}async*_traverseIdSet(e,t,r,i){for(let a=0;a<t.length;a+=r){e.objectIds=t.slice(a,a+r),s(i);const l=await this.executeQuery(e,"execute");yield l.features}}async queryStat(e){await this._ensureLoaded();const t=this._layer.capabilities?.query,r=!!t?.supportsSqlExpression,i=!!t?.supportsStatistics,a=!!t?.supportsDistinct,s=_(e.stat);if("count"===s)return a?this._queryCount(e):{calculated:!1};const n=e.field;if(null==n)return{calculated:!1};if(!1===i||!1===p(n)&&!1===r||!1===n.isStandardized)return null!=e.spatialFilter||null!=e.where?{calculated:!1}:this._manualStat(e.stat,n,e.limit??c,e.abortSignal);if("distinct"===s)return!1===a?null!=e.spatialFilter||null!=e.where?{calculated:!1}:this._manualStat(s,n,e.limit??c,e.abortSignal):{calculated:!1};const o=await this.databaseType();if(this.isTable()&&null!=e.spatialFilter)return{calculated:!0,result:null};const u=this._createQuery();u.where=w(u.where,null==e.where?null==e.spatialFilter?"1=1":"":d(e.where,o)),null!=e.spatialFilter&&(u.spatialRelationship=this._makeRelationshipEnum(e.spatialFilter.relation),u.relationParameter=this._makeRelationshipParam(e.spatialFilter.relation),u.geometry=e.spatialFilter.geometry);const h=new q;h.statisticType=s,h.onStatisticField=d(n,o),h.outStatisticFieldName="ARCADE_STAT_RESULT",u.returnGeometry=!1;let y="ARCADE_STAT_RESULT";u.outStatistics=[h];const m=await this.executeQuery(u,"execute");if(!m.hasOwnProperty("features")||0===m.features.length)throw new l("InvalidStatResponse");let f=!1;const F=m.fields??[];for(const l of F)if("ARCADE_STAT_RESULT"===l.name.toUpperCase()){y=l.name,"esriFieldTypeDate"===l.type&&(f=!0);break}const S=m.features[0].attributes[y];return{calculated:!0,result:f&&null!=S?new Date(S):S}}async _queryCount(e){const t=await this.databaseType();if(this.isTable()&&null!=e.spatialFilter)return{calculated:!0,result:0};const r=this._createQuery();r.where=w(r.where,null==e.where?null==e.spatialFilter?"1=1":"":d(e.where,t)),null!=e.spatialFilter&&(r.spatialRelationship=this._makeRelationshipEnum(e.spatialFilter.relation),r.relationParameter=this._makeRelationshipParam(e.spatialFilter.relation),r.geometry=e.spatialFilter.geometry),r.returnGeometry=!1;return{calculated:!0,result:await this.executeQuery(r,"executeForCount")}}async canQueryAggregate(e){await this._ensureLoaded();let t=!1;const r=this._layer.capabilities?.query,i=!0===r?.supportsSqlExpression;if(null!=r&&!0===r.supportsStatistics&&!0===r.supportsOrderBy&&(t=!0),t)for(const a of e.statistics)(!1===a.workingexpr?.isStandardized||!1===p(a.workingexpr)&&!1===i)&&(t=!1);return t}async queryAggregate(e){if(await this._ensureLoaded(),this.isTable()&&null!=e.spatialFilter)return o;const t=await this.databaseType(),r=e.groupBy,i=e.orderBy;let a=null;if(!this._layer.capabilities.query.supportsPaginationOnAggregatedQueries){const e=this.getFieldsIndex();a={keyFields:r.map((t,r)=>({name:e.normalizeFieldName(t)??t,asc:null==i||1===i._directions[r]}))}}let s="",l=!1;null!=i&&!0===this._layer.capabilities?.query?.supportsOrderBy&&(null==a||m(r,0,r.length,i._fields,0,Math.min(i._fields.length,r.length),(e,t)=>e.toLowerCase()===t.toLowerCase()))&&(s=i.constructClause(),l=!0),""===s&&(s=r.join(","));const n=e.statistics.map(e=>new q({onStatisticField:null!==e.workingexpr?d(e.workingexpr,t):"",outStatisticFieldName:e.field,statisticType:e.toStatisticsName()}));let u=this._maxQueryRate();const c=this._layer.capabilities?.query.maxRecordCount;null!=c&&c<u&&(u=c);const h=null==e.where?null==e.spatialFilter?"1=1":"":d(e.where,t),y=this._createQuery();return y.where=w(y.where,h),null!=e.spatialFilter&&(y.spatialRelationship=this._makeRelationshipEnum(e.spatialFilter.relation),y.relationParameter=this._makeRelationshipParam(e.spatialFilter.relation),y.geometry=e.spatialFilter.geometry),y.orderByFields=""!==s?s.split(","):null,y.outFields=["*"],y.outStatistics=n,y.groupByFieldsForStatistics=r,y.returnGeometry=!1,null==a?{filterApplied:!0,spatialFilterApplied:!0,ordered:l,features:this._queryPaginated(y,u,e.abortSignal)}:{filterApplied:!0,spatialFilterApplied:!0,ordered:l,features:this._queryKeysetPaginated(y,a,e.abortSignal)}}async*_queryKeysetPaginated(e,t,r){const i=e.where;for(;;){if(null!=t.clause){if(!this._layer.capabilities.query.supportsOrderBy)throw new l("NotImplemented");e.where=w(i,d(t.clause,await this.databaseType()))}const a=await this.executeQuery(e,"execute");if(s(r),!a.hasOwnProperty("features"))throw new l("InvalidStatResponse");if(yield a.features,0===a.features.length||!0!==a.exceededTransferLimit)break;Q(t,a.features.at(-1))}}_createQuery(){const e=this._layer.createQuery();return e.returnZ=this.hasZ,e.returnM=this.hasM,this.datesInUnknownTimezone&&(e.timeReferenceUnknownClient=!0),this._requestStandardised&&(e.sqlFormat="standard"),this._useDefinitionExpression?"subtype-group"===this._layer.type&&(e.where=this._layer.definitionExpression):e.where=null,e}executeQuery(e,t){const r="execute"===t?async e=>{const t=await this._layer.source.queryFeaturesJSON(e);return u(t.features,t.spatialReference??this.spatialReference.toJSON()),t}:"executeForCount"===t?this._layer.queryFeatureCount.bind(this._layer):this._layer.queryObjectIds.bind(this._layer);let i=null;if(this._recentlyUsedQueries){const t=this.convertQueryToLruCacheKey(e);i=this._recentlyUsedQueries.getFromCache(t),null===i&&(i=r(e),this._recentlyUsedQueries.addToCache(t,i),i=i.catch(e=>{throw this._recentlyUsedQueries?.removeFromCache(t),e}))}return this._featureSetQueryInterceptor&&this._featureSetQueryInterceptor.preLayerQueryCallback({layer:this._layer,query:e,method:t}),null===i&&(i=r(e)),i}_fieldsIncludingObjectId(e){if(null===e)return[this.objectIdField];const t=e.slice();if(t.includes("*"))return t;let r=!1;for(const i of t)if(i.toUpperCase()===this.objectIdField.toUpperCase()){r=!0;break}return r||t.push(this.objectIdField),t}isTable(){return this._layer.isTable||null===this._layer.geometryType||"table"===this._layer.type||""===this._layer.geometryType||"esriGeometryNull"===this._layer.geometryType}_makeRelationshipEnum(e){if(e.includes("esriSpatialRelRelation"))return"relation";switch(e){case"esriSpatialRelRelation":return"relation";case"esriSpatialRelIntersects":return"intersects";case"esriSpatialRelContains":return"contains";case"esriSpatialRelOverlaps":return"overlaps";case"esriSpatialRelWithin":return"within";case"esriSpatialRelTouches":return"touches";case"esriSpatialRelCrosses":return"crosses";case"esriSpatialRelEnvelopeIntersects":return"envelope-intersects"}return e}_makeRelationshipParam(e){return e.includes("esriSpatialRelRelation")?e.split(":")[1]:""}static create(e,t,r,i,a){const s=new g({url:e,outFields:null===t?["*"]:t});return new v({layer:s,spatialReference:r,lrucache:i,interceptor:a})}relationshipMetadata(){return this._layer&&this._layer.source&&this._layer.source.sourceJSON?.relationships?this._layer.source.sourceJSON.relationships:[]}serviceUrl(){return y(this._layer.parsedUrl.path)}async queryAttachments(e,t,r,s,l){function n(e){const t=e.capabilities;return t?.data.supportsAttachment&&t?.operations.supportsQueryAttachments}const o=this._layer;if(!n(o))return[];const u=new R({objectIds:[e],returnMetadata:l});(t&&t>0||r&&r>0)&&(u.size=[t&&t>0?t:0,r&&r>0?r:t+1]),s&&s.length>0&&(u.attachmentTypes=s),this._featureSetQueryInterceptor&&this._featureSetQueryInterceptor.preLayerQueryCallback({layer:o,query:u,method:"attachments"});const c=await o.queryAttachments(u);return c?.[e]?c[e].map(t=>{const r=`${this._layer.parsedUrl.path}/${e}/attachments/${t.id}`;let s=null;return l&&t.exifInfo&&(s=a.convertJsonToArcade(t.exifInfo,"system",!0)),new i(t.id,t.name,t.contentType,t.size,r,s,t.keywords??null)}):[]}async queryRelatedFeatures(e){const r=b(e);r.f="json",this._requestStandardised&&(r.sqlFormat="standard"),this._featureSetQueryInterceptor&&this._featureSetQueryInterceptor.preRequestCallback({layer:this._layer,queryPayload:r,method:"relatedrecords",url:this._layer.parsedUrl.path+"/queryRelatedRecords"});const i=await t(this._layer.parsedUrl.path+"/queryRelatedRecords",{responseType:"json",query:r});if(i.data){const e={},t=i.data;if(t?.relatedRecordGroups){const r=t.spatialReference,i=!0===t.exceededTransferLimit;for(const a of t.relatedRecordGroups)u(a.relatedRecords,r),e[a.objectId]={features:a.relatedRecords,exceededTransferLimit:i}}return e}throw new l("InvalidRequest")}async getFeatureByObjectId(e,t){const r=this._createQuery();r.outFields=t,r.returnGeometry=!1,r.outSpatialReference=this.spatialReference,r.where=w(r.where,this.objectIdField+"="+e.toString()),this._featureSetQueryInterceptor&&this._featureSetQueryInterceptor.preLayerQueryCallback({layer:this._layer,query:r,method:"execute"});const i=await this._layer.source.queryFeaturesJSON(r);return 1===i.features.length?(u(i.features,i.spatialReference??this.spatialReference.toJSON()),i.features[0]):null}async getIdentityUser(){await this.load();const t=e?.findCredential(this._layer.url);return t?t.userId:null}async getOwningSystemUrl(){await this.load();const r=e?.findServerInfo(this._layer.url);if(r)return r.owningSystemUrl??"";let i=this._layer.url;const a=i.toLowerCase().indexOf("/rest/services");if(i=a>-1?i.slice(0,a):i,i){i+="/rest/info";try{const e=await t(i,{query:{f:"json"}});let r="";return e.data?.owningSystemUrl&&(r=e.data.owningSystemUrl),r}catch{return""}}return""}getDataSourceFeatureSet(){const e=new v({layer:this._layer,spatialReference:this.spatialReference??void 0,outFields:this._overrideFields??void 0,includeGeometry:!this._removeGeometry,lrucache:this._recentlyUsedQueries??void 0,interceptor:this._featureSetQueryInterceptor??void 0});return e._useDefinitionExpression=!1,e}get preferredTimeZone(){return this._layer.preferredTimeZone??null}get dateFieldsTimeZone(){return this._layer.dateFieldsTimeZone??null}get datesInUnknownTimezone(){return this._layer.datesInUnknownTimezone??!1}get editFieldsInfo(){return this._layer.editFieldsInfo??null}get timeInfo(){return this._layer.timeInfo??null}async getFeatureSetInfo(){if(this._featureSetInfo)return this._featureSetInfo;let e=null,r="serviceItemId"in this._layer?this._layer.serviceItemId:null;const i=this._layer.parsedUrl?.path??null;if(i){const a=await t(i,{responseType:"json",query:{f:"json"}});e=a?.data?.name??null,r=a?.data?.serviceItemId??null}const a=this._layer.title&&null!==(this._layer.parent??null);return this._featureSetInfo={layerId:this._layer.layerId,layerName:""===e?null:e,itemId:""===r?null:r,serviceLayerUrl:""===i?null:i,webMapLayerId:a?this._layer.id??null:null,webMapLayerTitle:a?this._layer.title??null:null,className:null,objectClassId:null},this._featureSetInfo}}export{v as default};