UNPKG

@arcgis/core

Version:

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

6 lines (5 loc) • 11.6 kB
/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.33/esri/copyright.txt for details. */ import{_ as e}from"../../../../../chunks/tslib.es6.js";import t from"../../../../../core/Accessor.js";import{equals as i}from"../../../../../core/arrayUtils.js";import{createTask as s}from"../../../../../core/asyncUtils.js";import r from"../../../../../core/Logger.js";import{throwIfAbortError as o}from"../../../../../core/promiseUtils.js";import{when as n}from"../../../../../core/reactiveUtils.js";import{union as a,equals as l,isSubsetOf as u,difference as d}from"../../../../../core/SetUtils.js";import{normalizeGlobalID as c}from"../../../../../core/uuid.js";import{property as h}from"../../../../../core/accessorSupport/decorators/property.js";import"../../../../../core/has.js";import{subclass as p}from"../../../../../core/accessorSupport/decorators/subclass.js";import{UpdatingHandles as f}from"../../../../../core/support/UpdatingHandles.js";import y from"../../../../../geometry/Extent.js";import{toExtent as m}from"../../../../../geometry/support/aaBoundingRect.js";import{unquantizeOptimizedFeatureSet as _,convertFromFeatureSet as g}from"../../../../../layers/graphics/featureConversionUtils.js";import{isHostedAgolService as F}from"../../../../../layers/support/arcgisLayerUrl.js";import{OptimizedFeatureSetParserContext as T}from"../../../../../rest/query/operations/pbfOptimizedFeatureSet.js";import{executeQueryForExtent as b,executeQueryPBF as P,executeQuery as v}from"../../../../../rest/query/operations/query.js";import I from"../../../../../rest/support/Query.js";import{StateType as O,PendingFeatureTile as S}from"./PendingFeatureTile.js";let j=class extends t{get _minimumVerticesPerFeature(){switch(this.store?.featureStore.geometryType){case"esriGeometryPoint":case"esriGeometryMultipoint":return 1;case"esriGeometryPolygon":return 4;case"esriGeometryPolyline":return 2}}get _mandatoryOutFields(){const e=new Set;return this.objectIdField&&e.add(this.objectIdField),this.globalIdField&&e.add(this.globalIdField),e}set outFields(e){const t=this._get("outFields"),i=a(e,this._mandatoryOutFields);l(i,t)||(this._set("outFields",i),u(i,t)||this.refresh())}get outFields(){return this._get("outFields")??this._mandatoryOutFields}set filter(e){const t=this._get("filter"),i=this._filterProperties(e);JSON.stringify(t)!==JSON.stringify(i)&&this._set("filter",i)}set customParameters(e){const t=this._get("customParameters");JSON.stringify(t)!==JSON.stringify(e)&&this._set("customParameters",e)}get _configuration(){return{filter:this.filter,customParameters:this.customParameters,tileInfo:this.tileInfo,tileSize:this.tileSize}}set tileInfo(e){const t=this._get("tileInfo");t!==e&&(null!=e&&null!=t&&JSON.stringify(e)===JSON.stringify(t)||(this._set("tileInfo",e),this.store.tileInfo=e))}set tileSize(e){this._get("tileSize")!==e&&this._set("tileSize",e)}get updating(){return this._updatingHandles.updating}get hasZ(){return this.store.featureStore.hasZ}constructor(e){super(e),this.suspended=!0,this._historicMoment=null,this.tilesOfInterest=[],this.availability=0,this._pendingTiles=new Map,this._updatingHandles=new f}initialize(){this._initializeFetchExtent(),this._updatingHandles.add((()=>this._configuration),(()=>this.refresh())),this._updatingHandles.add((()=>this.tilesOfInterest),(()=>{this._updatePriorities(),this._process()}),{sync:!0,initial:!0,equals:(e,t)=>i(e,t,(({id:e},{id:t})=>e===t))}),this.addHandles(n((()=>!this.suspended),(()=>this._process())))}_updatePriorities(){this.store.setPriorityOrderByKey(this.tilesOfInterest.map((e=>e.id??""))??[])}destroy(){this._pendingTiles.forEach((e=>this._deletePendingTile(e))),this._pendingTiles.clear(),this.store.destroy(),this.tilesOfInterest.length=0,this._updatingHandles.destroy()}refresh(){this.store.refresh(),this._pendingTiles.forEach((e=>this._deletePendingTile(e))),this._process()}async handleEdits(e){if(e.historicMoment&&(this._historicMoment=e.historicMoment),!e.addedFeatures.length&&!e.updatedFeatures.length&&!e.deletedFeatures.length)return;for(const s of this._pendingTiles.values())s.reset();const t={...e,deletedFeatures:e.deletedFeatures.map((({objectId:e,globalId:t})=>e&&-1!==e?e:this._lookupObjectIdByGlobalId(t)))},i=s((async e=>{try{await this.store.processEdits(t,((e,t)=>this._queryFeaturesById(e,t)),e),this._processPendingTiles()}catch(i){o(i),r.getLogger(this).warn("Failed to apply edits",i)}}));this.addHandles(i),await this._updatingHandles.addPromise(i.promise)}setHistoricMoment(e){e?.getTime()!==this._historicMoment?.getTime()&&(this._historicMoment=e,this.refresh())}_initializeFetchExtent(){if(!this.capabilities.query.supportsExtent||!F(this.url))return;const e=s((async e=>{try{const t=await b(this.url,new I({where:"1=1",outSpatialReference:this.spatialReference,cacheHint:this.capabilities.query.supportsCacheHint??void 0}),{query:this._configuration.customParameters,signal:e});this.store.extent=y.fromJSON(t.data?.extent)}catch(t){o(t),r.getLogger(this).warn("Failed to fetch data extent",t)}}));this._updatingHandles.addPromise(e.promise.then((()=>this._process()))),this.addHandles(e)}get debugInfo(){return{numberOfFeatures:this.store.featureStore.numFeatures,tilesOfInterest:this.tilesOfInterest,pendingTiles:Array.from(this._pendingTiles.values()).map((e=>e.debugInfo)),storedTiles:this.store.debugInfo}}_process(){this._markTilesNotAlive(),this._createPendingTiles(),this._deletePendingTiles(),this._processPendingTiles()}_markTilesNotAlive(){for(const e of this._pendingTiles.values())e.alive=!1}_createPendingTiles(){if(this.suspended)return;const e=this._collectMissingTilesInfo();if(this._setAvailability(null==e?1:e.coveredArea/e.fullArea),null!=e)for(const{data:t,resolution:i}of e.missingTiles){const e=this._pendingTiles.get(t.id);e?(e.resolution=i,e.alive=!0):this._createPendingTile(t,i)}}_collectMissingTilesInfo(){let e=null;for(const t of this.tilesOfInterest){const i=this.store.process(t,((e,t)=>this._verifyTileComplexity(e,t)),this.outFields);null==e?e=i:e.prepend(i)}return e}_deletePendingTiles(){for(const e of this._pendingTiles.values())e.alive||this._deletePendingTile(e)}_processPendingTiles(){const e={fetchCount:(e,t)=>this._fetchCount(e,t),fetchFeatures:(e,t,i)=>this._fetchFeatures(e,t,i),finish:(e,t)=>this._finishPendingTile(e,t),resume:()=>this._processPendingTiles()};if(this._ensureFetchAllCounts(e))for(const t of this._pendingTiles.values())this._verifyTileComplexity(this.store.getFeatureCount(t.data),t.resolution)&&this._updatingHandles.addPromise(t.process(e))}_verifyTileComplexity(e,t){return this._verifyVertexComplexity(e)&&this._verifyFeatureDensity(e,t)}_verifyVertexComplexity(e){return e*this._minimumVerticesPerFeature<w}_verifyFeatureDensity(e,t){if(null==this.tileInfo)return!1;const i=this.tileSize*t;return e*(q/(i*i))<M}_ensureFetchAllCounts(e){let t=!0;for(const i of this._pendingTiles.values())i.state.type<O.FETCHED_COUNT&&this._updatingHandles.addPromise(i.process(e)),i.state.type<=O.FETCH_COUNT&&(t=!1);return t}_finishPendingTile(e,t){this.store.add(e.data,t),this._deletePendingTile(e),this._updateAvailability()}_updateAvailability(){const e=this._collectMissingTilesInfo();this._setAvailability(null==e?1:e.coveredArea/e.fullArea)}_setAvailability(e){this._set("availability",e)}_createPendingTile(e,t){const i=new S(e,t);return this._pendingTiles.set(e.id,i),i}_deletePendingTile(e){e.reset(),this._pendingTiles.delete(e.data.id)}async _fetchCount(e,t){return this.store.fetchCount(e.data,this.url,this._createCountQuery(e),{query:this.customParameters,timeout:x,signal:t})}async _fetchFeatures(e,t,i){let s=0;const r=[];let o=0,n=t;for(;;){const a=this._createFeaturesQuery(e),l=this._setPagingParameters(a,s,n),{features:u,exceededTransferLimit:d}=await this._queryFeatures(a,i);l&&(s+=a.num),o+=u.length;for(const e of u)r.push(e);if(n=t-o,!l||!d||n<=0)return r}}_filterProperties(e){return null==e?{where:"1=1",gdbVersion:void 0,timeExtent:void 0}:{where:e.where||"1=1",timeExtent:e.timeExtent,gdbVersion:e.gdbVersion}}_lookupObjectIdByGlobalId(e){const t=this.globalIdField,i=this.objectIdField;if(null==t)throw new Error("Expected globalIdField to be defined");let s=null;const r=e?c(e):e;if(this.store.featureStore.forEach((e=>{r===c(e.attributes[t])&&(s=e.objectId??e.attributes[i])})),null==s)throw new Error(`Expected to find a feature with globalId ${e}`);return s}_queryFeaturesById(e,t){const i=this._createFeaturesQuery();return i.objectIds=e,this._queryFeatures(i,t)}_queryFeatures(e,t){return this.capabilities.query.supportsFormatPBF?this._queryFeaturesPBF(e,t):this._queryFeaturesJSON(e,t)}async _queryFeaturesPBF(e,t){const{sourceSpatialReference:i}=this,{data:s}=await P(this.url,e,new T({sourceSpatialReference:i}),{query:this._configuration.customParameters,timeout:x,signal:t});return _(s)}async _queryFeaturesJSON(e,t){const{sourceSpatialReference:i}=this,{data:s}=await v(this.url,e,i,{query:this._configuration.customParameters,timeout:x,signal:t});return g(s,{type:"object-id",fieldName:this.objectIdField})}_createCountQuery(e){const t=this._createBaseQuery(e);return this.capabilities.query.supportsCacheHint&&(t.cacheHint=!0),t}_createFeaturesQuery(e=null){const t=this._createBaseQuery(e),i=null!=e?.data?this.store.getAttributesForTile(e?.data?.id):null,s=a(d(this.outFields,i??new Set),this._mandatoryOutFields);return t.outFields=Array.from(s),t.returnGeometry=!0,null!=e&&(this.capabilities.query.supportsResultType?t.resultType="tile":this.capabilities.query.supportsCacheHint&&(t.cacheHint=!0)),t}_createBaseQuery(e){const t=new I({returnZ:this.hasZ,returnM:!1,historicMoment:this._historicMoment,geometry:null!=this.tileInfo&&null!=e?m(e.data.extent,this.tileInfo.spatialReference):void 0}),i=this._configuration.filter;return null!=i&&(t.where=i.where,t.gdbVersion=i.gdbVersion,t.timeExtent=i.timeExtent),t.outSpatialReference=this.spatialReference,t}_setPagingParameters(e,t,i){if(!this.capabilities.query.supportsPagination)return!1;const{supportsMaxRecordCountFactor:s,supportsCacheHint:r,tileMaxRecordCount:o,maxRecordCount:n,supportsResultType:a}=this.capabilities.query,l=s?I.MAX_MAX_RECORD_COUNT_FACTOR:1,u=l*((a||r)&&o?o:n||C);return e.start=t,s?(e.maxRecordCountFactor=Math.min(l,Math.ceil(i/u)),e.num=Math.min(i,e.maxRecordCountFactor*u)):e.num=Math.min(i,u),!0}};e([h({constructOnly:!0})],j.prototype,"url",void 0),e([h({constructOnly:!0})],j.prototype,"objectIdField",void 0),e([h({constructOnly:!0})],j.prototype,"globalIdField",void 0),e([h({constructOnly:!0})],j.prototype,"capabilities",void 0),e([h({constructOnly:!0})],j.prototype,"sourceSpatialReference",void 0),e([h({constructOnly:!0})],j.prototype,"spatialReference",void 0),e([h({constructOnly:!0})],j.prototype,"store",void 0),e([h({readOnly:!0})],j.prototype,"_minimumVerticesPerFeature",null),e([h()],j.prototype,"_mandatoryOutFields",null),e([h()],j.prototype,"outFields",null),e([h()],j.prototype,"suspended",void 0),e([h()],j.prototype,"_historicMoment",void 0),e([h()],j.prototype,"filter",null),e([h()],j.prototype,"customParameters",null),e([h({readOnly:!0})],j.prototype,"_configuration",null),e([h()],j.prototype,"tileInfo",null),e([h()],j.prototype,"tileSize",null),e([h()],j.prototype,"tilesOfInterest",void 0),e([h({readOnly:!0})],j.prototype,"updating",null),e([h({readOnly:!0})],j.prototype,"availability",void 0),e([h()],j.prototype,"hasZ",null),j=e([p("esri.views.interactive.snapping.featureSources.featureServiceSource.FeatureServiceTiledFetcher")],j);const C=2e3,x=6e5,w=1e6,q=25,M=1;export{j as FeatureServiceTiledFetcher};