@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
3 lines (2 loc) • 13.2 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.19/LICENSE.txt */
import{__decorate as e}from"tslib";import t from"../../../../request.js";import r from"../../../../core/Accessor.js";import{splitIntoChunks as s}from"../../../../core/arrayUtils.js";import{createTask as i,resultOrAbort as n,result as o}from"../../../../core/asyncUtils.js";import a from"../../../../core/Collection.js";import{makeHandle as d}from"../../../../core/handleUtils.js";import"../../../../core/has.js";import c from"../../../../core/Logger.js";import{abortMaybe as h,destroyMaybe as l}from"../../../../core/maybe.js";import{estimateNumberMemory as u,estimateStringMemory as m}from"../../../../core/memoryEstimations.js";import{whenOrAbort as g,createResolver as p}from"../../../../core/promiseUtils.js";import y from"../../../../core/ReactiveSet.js";import{watch as f,sync as _}from"../../../../core/reactiveUtils.js";import{property as b,subclass as v}from"../../../../core/accessorSupport/decorators.js";import{equals as O}from"../../../../geometry/support/spatialReferenceUtils.js";import{formatNumber as j}from"../../../../intl/number.js";import{getMaximumQuerySize as C,queryAllJSON as w}from"../../../../layers/support/featureQueryAll.js";let I=class extends r{constructor(e){super(e),this._warnMaximumChangedObjectsExceeded=!1,this._maximumNumberOfEditOVerrides=L,this._definitionExpressionDirty=!0,this._interactiveEditingSessions=new a,this.geometryOverrides=new a,this._clientGeometryCache=new Map,this._attributeChangedObjectIds=new y,this._geometryChangedObjectIds=new y,this._pendingFetchChangedObjectIds=null,this._pendingFetchAbortController=new AbortController,this._applyGeometryOverridesTask=null,this._featureIdLocks=new Map}initialize(){this._memCache=new A(this.memoryController.newCache(`i3s-attribute-overrides-${this.layer.uid}`)),this.addHandles(f(()=>this.layer.definitionExpression,async()=>{this._definitionExpressionDirty=!0,this._pendingFetchChangedObjectIds||(this._applyGeometryOverridesTask=h(this._applyGeometryOverridesTask),this._applyGeometryOverridesTask=i(e=>this._queryAndAddGeometryOverrides(e)),await this._applyGeometryOverridesTask.promise)},_)),this._pendingFetchChangedObjectIds=this._fetchChangedObjectIds(this._pendingFetchAbortController?.signal),this._pendingFetchChangedObjectIds.finally(()=>{this._pendingFetchAbortController=null,this._pendingFetchChangedObjectIds=null})}destroy(){this._set("layer",null),this._memCache=l(this._memCache),this._pendingFetchAbortController=h(this._pendingFetchAbortController),this._pendingFetchChangedObjectIds=null,this._featureIdLocks.clear()}get is3DOFL(){return null!=this._associatedLayer?.infoFor3D}get sortedGeometryChangedObjectIds(){return this.is3DOFL?[...this._geometryChangedObjectIds].sort((e,t)=>e-t):[]}get _associatedLayer(){return null==this.layer?null:this.layer.associatedLayer}get hasGeometryChanges(){return this._geometryChangedObjectIds.size>0}get updating(){return!!this.is3DOFL&&!!(this._pendingFetchChangedObjectIds||this._applyGeometryOverridesTask&&!this._applyGeometryOverridesTask.finished)}get isEmpty(){return null==this._pendingFetchChangedObjectIds&&0===this._attributeChangedObjectIds.size&&0===this._geometryChangedObjectIds.size}featureHasGeometryChanges(e){return this._geometryChangedObjectIds.has(e)}featureHasAttributeChanges(e){return this._attributeChangedObjectIds.has(e)}createInteractiveEditSession(e){this._attributeChangedObjectIds.add(e);const t=this._interactiveEditingSessions,r=new F(e,()=>{t.remove(r)});return t.unshift(r),r}async applyAttributeOverrides(e,t,r,s=[]){if(this._pendingFetchChangedObjectIds&&await g(this._pendingFetchChangedObjectIds,r),null==t)return;const{attributeData:i,loadedAttributes:n}=t;if(null==n||null==i||0===this._attributeChangedObjectIds.size)return;const o=new Set;for(const d of n)o.add(d.index);for(const d of s)o.has(d.index)||(n.push(d),i[d.name]=new Array(e.length));const a=await this._lockFeatureIds(e);try{const t={attributeData:i,loadedAttributes:n},s=this._getOverridesFromCache(e,t,this._attributeChangedObjectIds),{objectIds:o,fieldNames:a}=s;if(0===o.length||0===a.length)return;const d=await this._queryAttributeOverridesFromAssociatedLayer(o,a,r);if(null==d)return;this._processOverridesFromAssociatedLayer(e,d,a,t)}finally{a.remove()}}updateGeometry(e,t){this._geometryChangedObjectIds.add(e);const r=this._clientGeometryCache.get(e);if(null!=r&&(this.geometryOverrides.remove(r),this._clientGeometryCache.delete(e)),null!=t){const r={oid:e,mesh:t};this.geometryOverrides.add(r),this._clientGeometryCache.set(e,r)}}updateAttributeValue(e,t,r){this._attributeChangedObjectIds.add(e),this._cacheAttributeValue(e,t,r)}featureAdded(e){this.is3DOFL&&this._geometryChangedObjectIds.add(e),this._attributeChangedObjectIds.add(e)}_cacheAttributeValue(e,t,r){this._memCache.put(e,t,r)}_getOverridesFromCache(e,{loadedAttributes:t,attributeData:r},s){const i=new Array;for(const a of t)i[a.index]=r[a.name];const n=new Set,o=new Set;for(let a=0;a<e.length;a++){const r=e[a];if(s.has(r))for(const e of t){const t=this._attributeFromCache(r,e.index);void 0===t?(n.add(r),o.add(e.name)):i[e.index][a]=t}}return{objectIds:Array.from(n),fieldNames:Array.from(o)}}_attributeFromCache(e,t){const r=this._fromInteractiveEditingSession(e,t);return void 0!==r?r:this._memCache.get(e,t)}_fromInteractiveEditingSession(e,t){if(null!=this._interactiveEditingSessions)for(const r of this._interactiveEditingSessions){if(r.objectId!==e)continue;const s=r.getAttribute(t);if(void 0!==s)return s}}async _queryAttributeOverridesFromAssociatedLayer(e,t,r){if(0===e.length)return null;this._logWarningIfMaximumObjectsExceeded();const{associatedLayer:s}=this.layer;if(null==s)return null;const i=s.createQuery(),{objectIdField:n}=s,o=[n,...t];i.where=this.layer.definitionExpression||"1=1",i.returnGeometry=!1,i.outFields=o,i.cacheHint=!0;const a=await this._executeBatchQuery(s,e,i,r),d=[];for(const c of a)if(c.ok)for(const e of c.value.features)d.push(e);return d}async _queryGeometryOverridesFromAssociatedLayer(e,t){if(0===e.length||!this.is3DOFL)return null;const r=this.layer.associatedLayer,s=r.infoFor3D,{spatialReference:i}=r,{state:{viewingMode:n},spatialReference:o}=this.view,a=1===n,d=i.isGeographic;if(a&&!d)return c.getLogger(this).warn("unsupported-pcs-edits-in-global-view",this.layer.title,E(i,o,this.view.viewingMode,0)),null;if(!a&&d)return c.getLogger(this).warn("unsupported-gcs-edits-in-local-view",this.layer.title,E(i,o,this.view.viewingMode,0)),null;if(!(O(i,o)||a&&o.isWebMercator&&i.isWGS84))return c.getLogger(this).warn("unsupported-mismatched-spatial-reference-edits",this.layer.title,E(i,o,this.view.viewingMode,1)),null;this._logWarningIfMaximumObjectsExceeded();const{objectIdField:h,globalIdField:l}=r,u=[h,...null!=l?[l]:[]],m=r.createQuery();m.where=this.layer.definitionExpression||"1=1",m.returnGeometry=!0,m.outFields=u,m.cacheHint=!0,m.returnZ=r.hasZ,m.returnM=r.hasM;const{assetMapFromAssetMapsJSON:g,extractMesh:p}=await import("../../../../rest/support/meshFeatureSet.js"),y=await this._executeBatchQuery(r,e,m,t),f=[];for(const c of y){if(!c.ok)continue;const e=c.value,{assetMaps:t,features:r,globalIdFieldName:n}=e;if(null==t)continue;const o=g(s,t);for(const a of r){const e=p(a,n,i,s,o),t=a;null!=e?(t.geometry=e,f.push(t)):t.geometry=null}}return f}_logWarningIfMaximumObjectsExceeded(){if(!this._warnMaximumChangedObjectsExceeded)return;this._warnMaximumChangedObjectsExceeded=!1;let e=`The number of edited objects that are not yet cached in the scene service exceeds the maximum limit. Attribute changes will only be available for the first ${j(this._maximumNumberOfEditOVerrides)} objects. Please consider re-caching the scene service`;const t=this.layer.portalItem;e+=t?.loaded?` (${t.portal.url}/home/item.html?id=${t.id}#settings)`:` (${this.layer.parsedUrl.path})`,c.getLogger(this).warn("#queryOverrides()",this.layer.title,`${e}.`)}async _executeBatchQuery(e,t,r,i){if(0===t.length)return[];const o=C(e);t=[...t].sort((e,t)=>e-t);const a=s(t,o).map(t=>{const s=r.clone();return s.objectIds=t,n(w(e,s,{signal:i}))});return Promise.all(a)}_processOverridesFromAssociatedLayer(e,t,r,{loadedAttributes:s,attributeData:i}){const n=this._associatedLayer;if(null==n)return;const o=n.objectIdField,a=r.map(t=>(t in i||(i[t]=new Array(e.length)),i[t])),d=new Map(s.map(e=>[e.name,e.index])),c=r.map(e=>d.get(e)),h=new Map(Array.from(e,(e,t)=>[e,t]));for(const l of t){const e=l.attributes[o];for(let t=0;t<r.length;t++){const s=c[t],i=h.get(e),n=l.attributes[r[t]];a[t][i]=n,this._cacheAttributeValue(e,s,n)}}}async _fetchChangedObjectIds(e){const r=this.layer;await r.load({signal:e}),this._geometryChangedObjectIds.clear(),this._attributeChangedObjectIds.clear();const{associatedLayer:s}=r;if(null==s||!s.capabilities?.operations?.supportsChangeTracking)return;const i=this._getFetchChangedObjectIdsServerGen();if(null==i)return;const n=s.layerId,a=this.is3DOFL,d={...s.customParameters,f:"json",returnIdsOnly:!0,layers:`[${n}]`,returnUpdates:!0,returnDeletes:a,returnInserts:a,layerServerGens:JSON.stringify([{id:n,serverGen:i}])};if(null!=s.apiKey&&(d.token=s.apiKey),a){const e=s.infoFor3D;d.fieldsToCompare=JSON.stringify({fields:[...Object.values(e.transformFieldRoles),e.sourceHashField]})}const h=await o(t(`${s.url}/extractChanges`,{method:"post",query:d,timeout:G,signal:e}));if(!h.ok){const e=this.layer.title;c.getLogger(this).warn("extractChanges:unavailable",e,": could not obtain edited features that are not cached in the scene service. Display of features may not be up to date with the latest edits. Consider re-caching the scene service.")}if(h.ok&&1===h.value.data?.edits?.length){const t=h.value.data.edits[0],r=t?.objectIds,s=t?.fieldUpdates,i=r?.adds??[],n=r?.updates??[],o=r?.deletes??[],d=[...i,...n,...o],c=a?[...i,...s??n,...o]:[],l=Math.min(this._maximumNumberOfEditOVerrides,d.length);l<d.length&&(this._warnMaximumChangedObjectsExceeded=!0);const u=d.sort((e,t)=>e-t);for(let e=0;e<l;++e){const t=u[e];this._attributeChangedObjectIds.add(t)}for(const e of c)this._geometryChangedObjectIds.add(e);for(;this._definitionExpressionDirty;)await this._queryAndAddGeometryOverrides(e)}}async _queryAndAddGeometryOverrides(e){this._definitionExpressionDirty=!1;const t=this.layer,{associatedLayer:r}=t;if(null!=r&&r.capabilities?.operations?.supportsChangeTracking&&this.is3DOFL&&this._geometryChangedObjectIds.size>0){const t=await this._queryGeometryOverridesFromAssociatedLayer(Array.from(this._geometryChangedObjectIds),e);if(null!=t)for(const e of t)null!=e.geometry&&this.updateGeometry(e.attributes[r.objectIdField],e.geometry)}}_getFetchChangedObjectIdsServerGen(){const e=this.layer;if(null!=e.serviceUpdateTimeStamp?.lastUpdate)return e.serviceUpdateTimeStamp.lastUpdate;const t=e.associatedLayer;return null!=t?.serverGens?.minServerGen?t.serverGens.minServerGen:null}async _lockFeatureIds(e){const t=this._featureIdLocks;let r=!0;for(;r;){const s=new Array;for(const r of e){const e=t.get(r);e&&s.push(e)}0===s.length?r=!1:await Promise.all(s)}const s=p(),i=s.promise;for(const n of e)t.set(n,i);return d(()=>{for(const r of e)t.delete(r);s.resolve()})}get test(){}};e([b({constructOnly:!0})],I.prototype,"view",void 0),e([b({constructOnly:!0})],I.prototype,"layer",void 0),e([b({readOnly:!0})],I.prototype,"is3DOFL",null),e([b()],I.prototype,"_interactiveEditingSessions",void 0),e([b({readOnly:!0})],I.prototype,"sortedGeometryChangedObjectIds",null),e([b({readOnly:!0})],I.prototype,"geometryOverrides",void 0),e([b()],I.prototype,"_clientGeometryCache",void 0),e([b()],I.prototype,"_associatedLayer",null),e([b({constructOnly:!0})],I.prototype,"memoryController",void 0),e([b()],I.prototype,"_attributeChangedObjectIds",void 0),e([b()],I.prototype,"_geometryChangedObjectIds",void 0),e([b()],I.prototype,"hasGeometryChanges",null),e([b()],I.prototype,"_pendingFetchChangedObjectIds",void 0),e([b()],I.prototype,"_pendingFetchAbortController",void 0),e([b()],I.prototype,"_applyGeometryOverridesTask",void 0),e([b()],I.prototype,"updating",null),e([b()],I.prototype,"isEmpty",null),I=e([v("esri.views.3d.layers.i3s.I3SOverrides")],I);class F{constructor(e,t){this.objectId=e,this._remove=t,this._updates=new Map,this._isActive=!0}getAttribute(e){return this._updates.get(e)}setAttribute(e,t){this.isActive&&this._updates.set(e,t)}remove(){this.isActive&&(this._isActive=!1,this._remove())}get isActive(){return this._isActive}}class A{constructor(e){this._cache=e}destroy(){this._cache.destroy()}put(e,t,r){this._cache.put(this._getKey(e,t),new x(r))}get(e,t){return this._cache.get(this._getKey(e,t))?.value}_getKey(e,t){return`${e}-${t}`}}class x{constructor(e){this.value=e,this.usedMemory="string"==typeof e?m(e):u}}const G=1e4,L=5e4;function E(e,t,r,s){return`Displaying the edits of a SceneLayer with a${0===s?e.isGeographic?" geographic ":" projected ":" "}spatial reference (wkid:${e.wkid}) in ${r} viewing mode${1===s?` with spatial reference (wkid:${t.wkid}) `:" "}is not supported. No geometry edits will be displayed for this layer.\nPlease consider re-caching the scene service or changing the ${0===s?"viewing mode":"view spatial reference"} to display edits.`}export{I as I3SOverrides};