@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 7.14 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.32/esri/copyright.txt for details.
*/
import{createTask as e}from"../../../core/asyncUtils.js";import t from"../../../core/Error.js";import r from"../../../core/Logger.js";import{throwIfAborted as a,isAbortError as s}from"../../../core/promiseUtils.js";import o from"../../../core/Warning.js";import{equals as n}from"../../../geometry/support/spatialReferenceUtils.js";import{convertFromGeometry as i,convertToGeometry as u}from"../featureConversionUtils.js";import{executeQueryForSnapping as l}from"../data/executeQueryForSnapping.js";import h from"../data/FeatureStore.js";import{checkProjectionSupport as c,project as m}from"../data/projectionSupport.js";import{QueryEngine as p}from"../data/QueryEngine.js";import{validateGeoJSON as g,createOptimizedFeatures as d}from"./geojson/geojson.js";import{mixAttributes as f}from"./support/sourceUtils.js";import{getGetFeatureSpatialReference as y,getFeatureCount as _,getFeature as x}from"../../ogc/wfsUtils.js";import w from"../../support/FieldsIndex.js";import{isNumber as C}from"../../../support/guards.js";import{utc as R}from"../../../time/constants.js";const F="esri.layers.WFSLayer";class S{constructor(){this._customParameters=null,this._queryEngine=null,this._supportsPagination=!0}destroy(){this._queryEngine?.destroy(),this._queryEngine=null}async load(e,r={}){const{getFeatureUrl:s,getFeatureOutputFormat:o,fields:n,geometryType:i,featureType:u,maxRecordCount:l,maxTotalRecordCount:m,maxPageCount:g,objectIdField:d,customParameters:f}=e,{spatialReference:_,getFeatureSpatialReference:x}=y(s,u,e.spatialReference);try{await c(x,_)}catch{throw new t("unsupported-projection","Projection not supported",{inSpatialReference:x,outSpatialReference:_})}a(r),this._customParameters=f,this._featureType=u,this._fieldsIndex=w.fromLayerJSON({fields:n,dateFieldsTimeReference:n.some((e=>"esriFieldTypeDate"===e.type))?{timeZoneIANA:R}:null}),this._geometryType=i,this._getFeatureUrl=s,this._getFeatureOutputFormat=o,this._getFeatureSpatialReference=x,this._maxRecordCount=l,this._maxTotalRecordCount=m,this._maxPageCount=g,this._objectIdField=d,this._spatialReference=_;let C=await this._snapshotFeatures(r);if(C.errors.length>0&&(this._supportsPagination=!1,C=await this._snapshotFeatures(r),C.errors.length>0))throw C.errors[0];return this._queryEngine=new p({fieldsIndex:this._fieldsIndex,geometryType:i,hasM:!1,hasZ:!1,objectIdField:d,spatialReference:_,timeInfo:null,featureStore:new h({geometryType:i,hasM:!1,hasZ:!1})}),this._queryEngine.featureStore.addMany(C.features),{warnings:E(C),extent:(await this._queryEngine.fetchRecomputedExtents()).fullExtent}}async applyEdits(){throw new t("wfs-source:editing-not-supported","applyEdits() is not supported on WFSLayer")}async queryFeatures(e={},t={}){return await this._waitSnapshotComplete(),this._queryEngine.executeQuery(e,t.signal)}async queryFeatureCount(e={},t={}){return await this._waitSnapshotComplete(),this._queryEngine.executeQueryForCount(e,t.signal)}async queryObjectIds(e={},t={}){await this._waitSnapshotComplete();return(await this._queryEngine.executeQueryForIds(e,t.signal)).filter(C)}async queryExtent(e={},t={}){return await this._waitSnapshotComplete(),this._queryEngine.executeQueryForExtent(e,t.signal)}async querySnapping(e,t={}){return await this._waitSnapshotComplete(),l(this._queryEngine,e,t.signal)}async queryAttributeBins(e,t={}){return await this._waitSnapshotComplete(),this._queryEngine.executeAttributeBinsQuery(e,t.signal)}async refresh(t){return this._customParameters=t.customParameters,this._maxRecordCount=t.maxRecordCount,this._maxTotalRecordCount=t.maxTotalRecordCount,this._maxPageCount=t.maxPageCount,this._snapshotTask?.abort(),this._snapshotTask=e((e=>this._snapshotFeatures({signal:e}))),this._snapshotTask.promise.then((e=>{this._queryEngine.featureStore.clear(),this._queryEngine.featureStore.addMany(e.features);for(const t of E(e))r.getLogger(F).warn(new o("wfs-layer:refresh-warning",t.message,t.details));e.errors?.length&&r.getLogger(F).warn(new o("wfs-layer:refresh-error","Refresh completed with errors",{errors:e.errors}))}),(()=>{this._queryEngine.featureStore.clear()})),await this._waitSnapshotComplete(),{extent:(await this._queryEngine.fetchRecomputedExtents()).fullExtent}}async _waitSnapshotComplete(){if(this._snapshotTask&&!this._snapshotTask.finished){try{await this._snapshotTask.promise}catch{}return this._waitSnapshotComplete()}}async _snapshotFeatures(e){const t=e?.signal,r=this._maxTotalRecordCount,o=this._maxPageCount,n=this._supportsPagination?await _(this._getFeatureUrl,this._featureType.typeName,{customParameters:this._customParameters,signal:t}):void 0;let i=[];const u=[];if(null==n)try{i=await this._singleQuery(t)}catch(l){s(l)||u.push(l)}else{const e=Math.min(n,r),a=T(this,Math.max(1,Math.min(Math.ceil(e/this._maxRecordCount),o)),t);await Promise.allSettled(Array.from({length:10}).map((()=>j(a,i,u))))}return a(t),{features:i,totalRecordCount:n,maxTotalRecordCount:r,maxPageCount:o,errors:u}}async _singleQuery(e){const t=await x(this._getFeatureUrl,this._featureType.typeName,this._getFeatureSpatialReference,this._getFeatureOutputFormat,{customParameters:this._customParameters,signal:e});return this._processGeoJSON(t,{signal:e})}async _pageQuery(e,t){const r=e*this._maxRecordCount,a=await x(this._getFeatureUrl,this._featureType.typeName,this._getFeatureSpatialReference,this._getFeatureOutputFormat,{customParameters:this._customParameters,startIndex:r,count:this._maxRecordCount,signal:t});return this._processGeoJSON(a,{startIndex:r,signal:t})}_processGeoJSON(e,t){g(e,this._getFeatureSpatialReference.wkid);const{startIndex:r,signal:s}=t;a(s);const o=d(e,{geometryType:this._geometryType,hasZ:!1,objectIdField:this._objectIdField});if(!n(this._spatialReference,this._getFeatureSpatialReference))for(const a of o)null!=a.geometry&&(a.geometry=i(m(u(a.geometry,this._geometryType,!1,!1),this._getFeatureSpatialReference,this._spatialReference)));let l=r??1;for(const a of o){const e={};f(this._fieldsIndex,e,a.attributes,!0),a.attributes=e,null==e[this._objectIdField]&&(a.objectId=e[this._objectIdField]=l++)}return o}}function*T(e,t,r){for(let a=0;a<t;a++)yield e._pageQuery(a,r)}async function j(e,t,r){let a=e.next();for(;!a.done;){try{const e=await a.value;t.push(...e)}catch(o){s(o)||r.push(o)}a=e.next()}}function E(e){const t=[];return null!=e.totalRecordCount&&(e.features.length<e.totalRecordCount&&t.push({name:"wfs-layer:maxRecordCount-too-low",message:`Could only fetch ${e.features.length} of ${e.totalRecordCount} in ${e.maxPageCount} queries. Try increasing the value of WFSLayer.maxRecordCount.`,details:{recordCount:e.features.length,totalRecordCount:e.totalRecordCount}}),e.totalRecordCount>e.maxTotalRecordCount&&t.push({name:"wfs-layer:large-dataset",message:`The number of ${e.totalRecordCount} features exceeds the maximum allowed of ${e.maxTotalRecordCount}.`,details:{recordCount:e.features.length,totalRecordCount:e.totalRecordCount,maxTotalRecordCount:e.maxTotalRecordCount}})),t}export{S as default};