UNPKG

@arcgis/core

Version:

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

3 lines (2 loc) 8.84 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */ import{__decorate as e}from"tslib";import t from"../../../core/Accessor.js";import{isSome as r}from"../../../core/arrayUtils.js";import{destroyHandle as a}from"../../../core/handleUtils.js";import"../../../core/has.js";import{mapCollectionAsync as n}from"../../../core/mapCollectionUtils.js";import{allSettledValues as s,throwIfAborted as i}from"../../../core/promiseUtils.js";import{watch as o,sync as c}from"../../../core/reactiveUtils.js";import{getMetersPerUnitForSR as u,getMetersPerVerticalUnitForSR as l}from"../../../core/units.js";import{property as p,subclass as d}from"../../../core/accessorSupport/decorators.js";import{squaredDistance as m}from"../../../core/libs/gl-matrix-2/math/vec2.js";import{copy as S,squaredDistance as h}from"../../../core/libs/gl-matrix-2/math/vec3.js";import{create as g}from"../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{getEpsilon as f}from"../../../core/libs/gl-matrix-2/math/common.js";import{UpdatingHandles as y}from"../../../core/support/UpdatingHandles.js";import{absoluteHeightElevationInfo as _}from"../../../support/elevationInfoUtils.js";import{VerticalHalfPlaneConstraint as v,isLine as w,isDrapedLine as j}from"../sketch/constraints.js";import{fromAnyMapPoint as F,asVec2 as b,markAsTarget as x}from"../sketch/normalizedPoint.js";import{FeatureSnappingSourceInfo as C}from"./FeatureSnappingSourceInfo.js";import{sortCandidatesInPlace as R,screenDistance as M}from"./snappingUtils.js";import{DrapedEdgeSnappingCandidate as I}from"./candidates/DrapedEdgeSnappingCandidate.js";import{EdgeSnappingCandidate as L}from"./candidates/EdgeSnappingCandidate.js";import{FeatureSnappingCandidate as G}from"./candidates/FeatureSnappingCandidate.js";import{RightAngleSnappingCandidate as H}from"./candidates/RightAngleSnappingCandidate.js";import{vectorToScreenPoint as P}from"../support/viewUtils.js";let z=class extends t{get updating(){return this._snappingSources.some(e=>null==e?.valid||!0===e.valid&&!0===e.snappingSource?.updating)||this._updatingHandles.updating}constructor(e){super(e),this.options=null,this._domain=1,this._updatingHandles=new y,this._sourceModules={featureService:{module:null,loader:null},featureCollection:{module:null,loader:null},graphics:{module:null,loader:null},notes:{module:null,loader:null},scene:{module:null,loader:null}}}initialize(){const e=n(()=>this.options?._effectiveFeatureSources,(e,t)=>this._createSourceInfo(e,t));this._snappingSources=e,this.addHandles([a(e),o(()=>({rulesEnabled:!!this.options?.attributeRulesEnabled,sources:this._snappingSources.filter(r)}),({rulesEnabled:e,sources:t})=>{for(const r of t)r.attributeRulesEnabled=e},c)])}destroy(){this._set("options",null),this._updatingHandles.destroy()}async fetchCandidates(e,t,r,a){if(!(t&this._domain&&null!=this.options&&this.options.effectiveFeatureEnabled))return[];const n=new Array,o=this._computeScreenSizeDistanceParameters(e,r);for(const s of this._snappingSources){if(!s?.valid||!s.snappingSource?.layerSource?.enabled||s.layerView?.suspended)continue;const t=s.getFetchCandidatesParameters(e,r,o);for(const e of t)n.push(s.snappingSource.fetchCandidates(e,a).then(e=>this._processCandidatesFromSource(s,e,r)))}const c=(await s(n)).flat();return this._addRightAngleCandidates(c,e,o,r),i(a),R(e,c),c}_addRightAngleCandidates(e,t,r,a){const n=null!=a.vertexHandle?a.vertexHandle.rightSegment?.rightVertex?.pos:null!=a.editGeometryOperations&&"polygon"===a.editGeometryOperations.data.type?a.editGeometryOperations.data.parts[0]?.getFirstVertex()?.pos:null,s=null!=a.vertexHandle?a.vertexHandle.leftSegment?.leftVertex?.pos:null!=a.editGeometryOperations?a.editGeometryOperations.data.parts[0]?.getLastVertex()?.pos:null,{view:i}=this,o=F(n,i,a),c=F(s,i,a),u=e.length;for(let l=0;l<u;l++)this._addRightAngleCandidate(e[l],c,t,r,e),this._addRightAngleCandidate(e[l],o,t,r,e)}_addRightAngleCandidate(e,t,r,a,n){if(null==t||!A(e))return;const s=e.constraint.closestTo(t),i=(s[0]-r[0])/a.x,o=(s[1]-r[1])/a.y,{start:c,end:u}=e.constraint;if(i*i+o*o<=1){const r=m(b(s),b(c))>m(b(s),b(u))?c:u,a=new H({targetPoint:x(s),otherVertex:t,otherVertexType:0,previousVertex:r,constraint:new v(t,s),objectId:e.objectId,isDraped:e.isDraped,domain:1});n.push(a)}}_computeScreenSizeDistanceParameters(e,t){let r=null!=this.options?this.options.distance*("touch"===t.pointer?this.options.touchSensitivityMultiplier:1):0;return null==this.view?{x:r,y:r,z:r,distance:r}:"2d"===this.view.type?(r*=this.view.resolution,{x:r,y:r,z:r,distance:r}):this._computeScreenSizeDistanceParameters3D(e,r,this.view,t)}_computeScreenSizeDistanceParameters3D(e,t,r,a){const{spatialReference:n}=a;r.renderCoordsHelper.toRenderCoords(e,n,O);const s=r.state.camera.computeScreenPixelSizeAt(O),i=s*r.renderCoordsHelper.unitInMeters,o=i/u(n),c=i/l(n),p=t*o,d=t*c,m=P(e,n,_,r),S=m?E(m,e,o,0,0,r,a):0,h=m?E(m,e,0,o,0,r,a):0,g=m?E(m,e,0,0,c,r,a):0;return{x:0===S?0:p/S,y:0===h?0:p/h,z:0===g?0:d/g,distance:s*t}}_processCandidatesFromSource(e,t,r){const a=[];for(const n of t)e.snappingSource&&!this._candidateIsExcluded(e.snappingSource,n,r.excludeFeature)&&(n instanceof G&&(n.layer=e.layer),a.push(n));return a}_candidateIsExcluded(e,t,r){if(null==r)return!1;const a=this._getCandidateObjectId(t);if(null==a)return!1;const n=e.layerSource.layer;return"graphics"===n.type?r.uid===a:r.sourceLayer===n&&(!(!r.attributes||!("objectIdField"in n))&&r.attributes[n.objectIdField]===a)}_getCandidateObjectId(e){return e instanceof G?e.objectId:null}async _createSourceInfo(e,t){const r=e.layer;r.loaded||(await r.load(),i(t));const{view:a}=this,n=await this._createFeatureSnappingSourceType(e);return i(t),new C(null==n?{}:{snappingSource:n,view:a,layer:r})}async _createFeatureSnappingSourceType(e){switch(e.layer.type){case"feature":case"geojson":case"csv":case"oriented-imagery":case"subtype-group":case"wfs":return this._createFeatureSnappingSourceFeatureLayer(e);case"graphics":return this._createFeatureSnappingSourceGraphicsLayer(e);case"map-notes":return this._createFeatureSnappingSourceMapNotesLayer(e);case"scene":case"building-scene":return this._createFeatureSnappingSourceSceneLayer(e)}return null}async _createFeatureSnappingSourceSceneLayer(e){const{view:t}=this;if(null==t||"3d"!==t.type)return null;return new((await this._getSourceModule("scene")).SceneLayerSnappingSource)({layerSource:e,view:t})}async _createFeatureSnappingSourceFeatureLayer(e){switch(e.layer.source?.type){case"feature-layer":case"oriented-imagery":return new((await this._getSourceModule("featureService")).FeatureServiceSnappingSource)({spatialReference:this.spatialReference,view:this.view,layerSource:e});case"memory":case"csv":case"geojson":case"wfs":if("mesh"===e.layer.geometryType)return null;return new((await this._getSourceModule("featureCollection")).FeatureCollectionSnappingSource)({layerSource:e,view:this.view})}return null}async _createFeatureSnappingSourceGraphicsLayer(e){return new((await this._getSourceModule("graphics")).GraphicsSnappingSource)({getGraphicsLayers:()=>[e.layer],spatialReference:this.spatialReference,view:this.view,layerSource:e})}async _createFeatureSnappingSourceMapNotesLayer(e){return new((await this._getSourceModule("notes")).GraphicsSnappingSource)({getGraphicsLayers:()=>e.layer.sublayers?.toArray()??[],spatialReference:this.spatialReference,view:this.view,layerSource:e})}async _getSourceModule(e){const t=this._sourceModules[e];if(null==t.loader){const t=this._loadSourceModule(e),r={module:null,loader:t};this._sourceModules[e]=r;const a=await t,n={module:a,loader:t};return this._sourceModules[e]=n,a}return null==t.module?t.loader:t.module}_loadSourceModule(e){const t=this._updatingHandles;switch(e){case"featureService":return t.addPromise(import("./featureSources/FeatureServiceSnappingSource.js"));case"featureCollection":return t.addPromise(import("./featureSources/FeatureCollectionSnappingSource.js"));case"graphics":case"notes":return t.addPromise(import("./featureSources/GraphicsSnappingSource.js"));case"scene":return t.addPromise(import("./featureSources/SceneLayerSnappingSource.js"))}}get test(){}};function A(e){const t=e instanceof L||e instanceof I,r=w(e.constraint)||j(e.constraint);return t&&r&&!D(e.constraint)}function D({start:e,end:t}){const r=h(e,t),a=m(b(e),b(t));return r<f()||a/r<V}function E(e,t,r,a,n,s,{spatialReference:i}){const o=S(U,t);o[0]+=r,o[1]+=a,o[2]+=n;const c=P(o,i,_,s);return c?M(c,e):1/0}e([p({constructOnly:!0})],z.prototype,"spatialReference",void 0),e([p({constructOnly:!0})],z.prototype,"view",void 0),e([p()],z.prototype,"options",void 0),e([p({readOnly:!0})],z.prototype,"updating",null),e([p()],z.prototype,"_snappingSources",void 0),z=e([d("esri.views.interactive.snapping.FeatureSnappingEngine")],z);const O=g(),U=g(),V=1e-4;export{z as FeatureSnappingEngine};