@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 9.19 kB
JavaScript
/*
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{removeUnordered as o}from"../../../../core/arrayUtils.js";import{createTask as r}from"../../../../core/asyncUtils.js";import{memoize as s}from"../../../../core/memoize.js";import{throwIfAborted as i,allSettledValues as n,whenOrAbort as a}from"../../../../core/promiseUtils.js";import{initial as p,watch as l,on as d}from"../../../../core/reactiveUtils.js";import{property as c}from"../../../../core/accessorSupport/decorators/property.js";import"../../../../core/has.js";import"../../../../core/Logger.js";import{subclass as u}from"../../../../core/accessorSupport/decorators/subclass.js";import{UpdatingHandles as h}from"../../../../core/support/UpdatingHandles.js";import y from"../../../../geometry/Polygon.js";import{initializeProjection as m,canProjectWithoutEngine as g,project as f}from"../../../../geometry/projectionUtils.js";import{normalizeCentralMeridianForDisplay as _}from"../../../../geometry/support/normalizeUtilsSync.js";import{featureGeometryTypeKebabDictionary as v}from"../../../../geometry/support/typeUtils.js";import{convertFromGeometry as S}from"../../../../layers/graphics/featureConversionUtils.js";import{OptimizedFeature as w}from"../../../../layers/graphics/OptimizedFeature.js";import{executeQueryForSnapping as j}from"../../../../layers/graphics/data/executeQueryForSnapping.js";import b from"../../../../layers/graphics/data/FeatureStore.js";import{QueryEngine as E}from"../../../../layers/graphics/data/QueryEngine.js";import k from"../../../../layers/support/FieldsIndex.js";import{elevationContextAffectsAlignment as C}from"../../../../support/elevationInfoUtils.js";import{symbolHasExtrudeSymbolLayer as F}from"../../../../symbols/support/utils.js";import{sortCandidatesInPlace as A,makeSnappingQuery as I}from"../snappingUtils.js";import{makeGetGroundElevation as P,convertSnappingCandidate as G}from"./queryEngineUtils.js";import{getSnappingCandidateElevationAligner as H}from"./snappingCandidateElevationAlignment.js";import{getSnappingCandidateElevationFilter as R}from"./snappingCandidateElevationFilter.js";import{getSymbologySnappingCandidatesFetcher as U}from"./symbologySnappingCandidates.js";import{TaskPriority as x}from"../../../support/Scheduler.js";const z="graphics-collections";let O=class extends t{get updating(){return this._updatingHandles.updating}get _hasZ(){const e=this.view;return null!=e&&"3d"===e.type&&"map-notes"!==this.layerSource.layer.type}get _snappingElevationAligner(){const{view:e}=this,{layer:t}=this.layerSource,o=null!=e&&"3d"===e.type;if(!o||"map-notes"===t.type)return H();const r=async(o,r)=>(await a(e.whenLayerView(t),r)).elevationAlignPointsInFeatures(o,r);return H(o,{elevationInfo:t.elevationInfo,alignPointsInFeatures:r})}get _snappingElevationFilter(){const{view:e}=this,t=null!=e&&"3d"===e.type&&"map-notes"!==this.layerSource.layer.type;return R(t)}get _symbologySnappingFetcher(){const{view:e}=this,{layer:t}=this.layerSource,o=null!=e&&"3d"===e.type,r=this._extrudedPolygonSymbolsCount>0;return o&&"map-notes"!==t.type&&r?U(r,(async(o,r)=>{const s=await e.whenLayerView(t);return i(r),s.queryForSymbologySnapping({candidates:o,spatialReference:e.spatialReference},r)})):U()}constructor(e){super(e),this.availability=1,this._sources={multipoint:null,point:null,polygon:null,polyline:null},this._loadedWkids=new Set,this._loadedWkts=new Set,this._pendingAdds=[],this._extrudedPolygonSymbolsCount=0,this._updatingHandles=new h,this._memoizedMakeGetGroundElevation=s(P)}destroy(){for(const e of this._pendingAdds)e.task.abort();this._pendingAdds.length=0,this._mapSources((e=>this._destroySource(e))),this._updatingHandles.destroy()}initialize(){this._updatingHandles.add((()=>this.getGraphicsLayers()),(e=>{this._updatingHandles.removeHandles(z);for(const t of e)this._addMany(t.graphics.toArray()),this.addHandles([t.on("graphic-update",(e=>this._onGraphicUpdate(e))),this._updatingHandles.addOnCollectionChange((()=>t.graphics),(e=>this._onGraphicsChanged(e)))],z)}),p);const{view:e}=this,{layer:t}=this.layerSource;null!=e&&"3d"===e.type&&"map-notes"!==t.type&&e.elevationProvider&&this.addHandles([e.elevationProvider.on("elevation-change",(({context:e})=>{C(e,t.elevationInfo)&&this._snappingElevationAligner.notifyElevationSourceChange()})),l((()=>t.elevationInfo),(()=>this._snappingElevationAligner.notifyElevationSourceChange()),p),d((()=>t),["edits","apply-edits","graphic-update"],(()=>this._symbologySnappingFetcher.notifySymbologyChange()))])}async fetchCandidates(e,t){const{point:o,coordinateHelper:{spatialReference:r}}=e,s=await n(this._mapSources((o=>this._fetchCandidatesForSource(o,e,t))));i(t);const a=this._memoizedMakeGetGroundElevation(this.view,r),p=s.flat().map((e=>G(e,a)));return A(o,p),p}async _fetchCandidatesForSource(e,t,o){const r=I({parameters:t,mode:this.view?.type??"2d"}),s=await j(e.queryEngine,r,o);i(o);const n=await this._snappingElevationAligner.alignCandidates(s.candidates,t.coordinateHelper.spatialReference,o);i(o);const a=await this._symbologySnappingFetcher.fetch(n,o);i(o);const p=0===a.length?n:[...n,...a];return this._snappingElevationFilter.filter(r,p)}refresh(){}_onGraphicUpdate(e){if(this.getGraphicsLayers().some((t=>t.graphics.includes(e.graphic))))switch(e.property){case"geometry":case"visible":this._remove(e.graphic),this._addMany([e.graphic])}}_onGraphicsChanged(e){for(const t of e.removed)this._remove(t);this._addMany(e.added)}_addMany(e){const t=[],o=new Map;for(const r of e)null!=r.geometry&&(this._needsInitializeProjection(r.geometry.spatialReference)?(t.push(r.geometry.spatialReference),o.set(r.uid,r)):this._add(r));this._createPendingAdd(t,o)}_createPendingAdd(e,t){if(!e.length)return;const s=r((async o=>{await m(e.map((e=>({source:e,dest:this.spatialReference}))),{signal:o}),this._markLoadedSpatialReferences(e);for(const e of t.values())this._add(e)}));this._updatingHandles.addPromise(s.promise);const i={task:s,graphics:t},n=()=>o(this._pendingAdds,i);s.promise.then(n,n),this._pendingAdds.push(i)}_markLoadedSpatialReferences(e){for(const t of e){null!=t.wkid&&this._loadedWkids.add(t.wkid);const e=t.wkt2||t.wkt;e&&this._loadedWkts.add(e)}}_add(e){if(null==e.geometry||!e.visible)return;let t=e.geometry;if("mesh"===t.type)return;"extent"===t.type&&(t=y.fromExtent(t));const o=this._ensureSource(t.type);if(null==o)return;const r=this._createOptimizedFeature(e.uid,t);null!=r&&(o.featureStore.add(r),F(e.symbol)&&this._extrudedPolygonSymbolsCount++)}_needsInitializeProjection(e){if(null!=e.wkid&&this._loadedWkids.has(e.wkid))return!1;const t=e.wkt2||e.wkt;return(!t||!this._loadedWkts.has(t))&&!g(e,this.spatialReference)}_createOptimizedFeature(e,t){const o=f(_(t),this.spatialReference);if(!o)return null;const r=this._ensureGeometryHasZ(o),s=S(r,this._hasZ,!1);return new w(s,{[Z]:e},null,e)}_ensureGeometryHasZ(e){if(!this._hasZ)return e;const t=e=>{for(;e.length<3;)e.push(0)},o=e.clone();switch(o.hasZ=!0,o.type){case"point":o.z=o.z??0;break;case"multipoint":o.points.forEach(t);break;case"polyline":o.paths.forEach((e=>e.forEach(t)));break;case"polygon":o.rings.forEach((e=>e.forEach(t)))}return o}_ensureSource(e){const t=this._sources[e];if(null!=t)return t;const o=this._createSource(e);return this._sources[e]=o,o}_createSource(e){const t=v.toJSON(e),o=this._hasZ,r=new b({geometryType:t,hasZ:o,hasM:!1});return{featureStore:r,queryEngine:new E({featureStore:r,fieldsIndex:k.fromLayerJSON({fields:[{name:Z,type:"esriFieldTypeOID",alias:Z}]}),geometryType:t,hasM:!1,hasZ:o,featureIdInfo:{type:"object-id",fieldName:Z},spatialReference:this.spatialReference,priority:x.SNAPPING,scheduler:null!=this.view&&"3d"===this.view.type?this.view.resourceController.scheduler:null}),type:e}}_remove(e){this._mapSources((t=>this._removeFromSource(t,e)));for(const t of this._pendingAdds)t.graphics.delete(e.uid),0===t.graphics.size&&t.task.abort()}_removeFromSource(e,t){const o=t.uid;e.featureStore.has(o)&&(e.featureStore.removeById(t.uid),F(t.symbol)&&this._extrudedPolygonSymbolsCount--)}_destroySource(e){e.queryEngine.destroy(),this._sources[e.type]=null}_mapSources(e){const{point:t,polygon:o,polyline:r,multipoint:s}=this._sources,i=[];return null!=t&&i.push(e(t)),null!=o&&i.push(e(o)),null!=r&&i.push(e(r)),null!=s&&i.push(e(s)),i}};e([c()],O.prototype,"getGraphicsLayers",void 0),e([c({constructOnly:!0})],O.prototype,"layerSource",void 0),e([c({constructOnly:!0})],O.prototype,"spatialReference",void 0),e([c({constructOnly:!0})],O.prototype,"view",void 0),e([c({readOnly:!0})],O.prototype,"updating",null),e([c({readOnly:!0})],O.prototype,"availability",void 0),e([c()],O.prototype,"_hasZ",null),e([c()],O.prototype,"_snappingElevationAligner",null),e([c()],O.prototype,"_snappingElevationFilter",null),e([c()],O.prototype,"_symbologySnappingFetcher",null),e([c()],O.prototype,"_extrudedPolygonSymbolsCount",void 0),O=e([u("esri.views.interactive.snapping.featureSources.GraphicsSnappingSource")],O);const Z="OBJECTID";export{O as GraphicsSnappingSource};