UNPKG

@doegis/core

Version:

DOE GIS API

3 lines (1 loc) 9.59 kB
import{_ as e}from"../../../chunks/tslib.es6.js";import{HandleOwner as t}from"../../../core/HandleOwner.js";import r from"../../../core/Handles.js";import{someMap as s}from"../../../core/MapUtils.js";import{isSome as o,isNone as n,unwrap as a}from"../../../core/maybe.js";import{eachAlwaysValues as i,throwIfAborted as c}from"../../../core/promiseUtils.js";import{sync as u,watch as p,syncAndInitial as d}from"../../../core/reactiveUtils.js";import{property as l}from"../../../core/accessorSupport/decorators/property.js";import"../../../core/accessorSupport/ensureType.js";import"../../../core/arrayUtils.js";import{subclass as h}from"../../../core/accessorSupport/decorators/subclass.js";import{k as g}from"../../../chunks/vec2.js";import{d as m,c as y}from"../../../chunks/vec3.js";import{c as S}from"../../../chunks/vec3f64.js";import{g as f}from"../../../chunks/common.js";import{SnappingTypes as w}from"../../../layers/graphics/data/QueryEngineResult.js";import{absoluteHeightElevationInfo as v}from"../../../support/elevationInfoUtils.js";import{VerticalHalfPlaneConstraint as _}from"./SnappingConstraint.js";import{SnappingDomain as j}from"./SnappingDomain.js";import{anyMapPointToSnappingPoint as C}from"./SnappingPoint.js";import{sortCandidatesInPlace as F,screenDistance as x}from"./snappingUtils.js";import{DrapedEdgeSnappingCandidate as b}from"./candidates/DrapedEdgeSnappingCandidate.js";import{EdgeSnappingCandidate as R}from"./candidates/EdgeSnappingCandidate.js";import{FeatureSnappingCandidate as L}from"./candidates/FeatureSnappingCandidate.js";import{RightAngleSnappingCandidate as M,OtherVertexType as E}from"./candidates/RightAngleSnappingCandidate.js";import{vectorToScreenPoint as H}from"../support/viewUtils.js";let V=class extends t{get updating(){return s(this.snappingSources,(({snappingSource:e})=>e.updating))||this.updatingHandles.updating}get snappingSources(){const e=this._get("snappingSources")||new Map,t=new Map;if(o(this.options)&&o(this.options.featureSources))for(const r of this.options.featureSources.items){const s=r.layer.uid,n=e.get(s);if(n){e.delete(s),t.set(s,n);continue}if(!r.layer.loaded){this.updatingHandles.addPromise(r.layer.load());continue}const a=this._createSourceInfo(r);o(a)&&t.set(s,a)}for(const[,r]of e)r.destroy();return t}constructor(e){super(e),this.options=null,this._domain=j.FEATURE,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(){this.updatingHandles.add((()=>this.snappingSources),(()=>this.notifyChange("updating")),u),o(this.view)&&this.handles.add([this.view.on("layerview-create",(e=>this._updateLayerView(e.layer,e.layerView))),this.view.on("layerview-destroy",(e=>this._updateLayerView(e.layer,null)))])}_updateLayerView(e,t){for(const[,r]of this.snappingSources)r.snappingSource.layerSource.layer===e&&(r.layerView=t)}destroy(){this._set("options",null);for(const[,e]of this.snappingSources)e.destroy()}async fetchCandidates(e,t,r,s){if(!(t&this._domain)||n(this.options)||!this.options.effectiveFeatureEnabled)return[];const u=[],p=this._computeScreenSizeDistanceParameters(e,r),d={distance:p,mode:a(this.view)?.type??"2d",point:e,coordinateHelper:r.coordinateHelper,types:this._types};for(const[,{snappingSource:n,layerView:a}]of this.snappingSources)!n.layerSource.enabled||o(a)&&a.suspended||u.push(n.fetchCandidates(d,s).then((e=>e.filter((e=>!this._candidateIsExcluded(n,e,r.excludeFeature))))));const l=(await i(u)).flat();return this._addRightAngleCandidates(l,e,p,r),c(s),F(e,l),l}_addRightAngleCandidates(e,t,r,s){const n=o(s.vertexHandle)?s.vertexHandle.rightEdge?.rightVertex?.pos:o(s.editGeometryOperations)&&"polygon"===s.editGeometryOperations.data.type?a(s.editGeometryOperations.data.components[0]?.getFirstVertex())?.pos:null,i=o(s.vertexHandle)?s.vertexHandle.leftEdge?.leftVertex?.pos:o(s.editGeometryOperations)?a(s.editGeometryOperations.data.components[0]?.getLastVertex())?.pos:null,{view:c}=this,u=C(n,c,s),p=C(i,c,s),d=e.length;for(let o=0;o<d;o++)this._addRightAngleCandidate(e[o],p,t,r,e),this._addRightAngleCandidate(e[o],u,t,r,e)}_addRightAngleCandidate(e,t,r,s,o){if(n(t)||!G(e))return;const a=e.constraint.closestTo(t),i=(a[0]-r[0])/s.x,c=(a[1]-r[1])/s.y,{start:u,end:p}=e.constraint;if(i*i+c*c<=1){const r=new M({targetPoint:a,otherVertex:t,otherVertexType:E.NEXT,previousVertex:g(a,u)>g(a,p)?u:p,constraint:new _(t,a),objectId:e.objectId,isDraped:e.isDraped});o.push(r)}}_computeScreenSizeDistanceParameters(e,t){let r=o(this.options)?this.options.distance*("touch"===t.pointer?this.options.touchSensitivityMultiplier:1):0;return n(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,s){const{spatialReference:o}=s;r.renderCoordsHelper.toRenderCoords(e,o,D);const n=r.state.camera.computeScreenPixelSizeAt(D),a=n*r.renderCoordsHelper.unitInMeters/r.mapCoordsHelper.unitInMeters,i=t*a,c=H(e,o,v,r),u=c?O(c,e,a,0,0,r,s):0,p=c?O(c,e,0,a,0,r,s):0,d=c?O(c,e,0,0,a,r,s):0;return{x:0===u?0:i/u,y:0===p?0:i/p,z:0===d?0:i/d,distance:n*t}}get _types(){return w.EDGE|w.VERTEX}_candidateIsExcluded(e,t,r){if(n(r))return!1;const s=this._getCandidateObjectId(t);if(n(s))return!1;const o=e.layerSource.layer;return"graphics"===o.type?r.uid===s:r.sourceLayer===o&&(!(!r.attributes||!("objectIdField"in o))&&r.attributes[o.objectIdField]===s)}_getCandidateObjectId(e){return e instanceof L?e.objectId:null}_createSourceInfo(e){const t=this._createFeatureSnappingSourceType(e);if(n(t))return null;if("loading"in t)return this.updatingHandles.addPromise(t.loading.then((()=>{this.destroyed||this.notifyChange("snappingSources")}))),null;const r=o(this.view)?this.view.allLayerViews.find((t=>t.layer===e.layer)):null;return new I(t.source,r)}_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}_createFeatureSnappingSourceSceneLayer(e){const{view:t}=this;if(n(t)||"3d"!==t.type)return null;const r=this._getSourceModule("scene");return o(r.module)?{source:new r.module.SceneLayerSnappingSource({layerSource:e,view:t})}:{loading:r.loader}}_createFeatureSnappingSourceFeatureLayer(e){switch(e.layer.source?.type){case"feature-layer":case"oriented-imagery":{const t=this._getSourceModule("featureService");return o(t.module)?{source:new t.module.FeatureServiceSnappingSource({spatialReference:this.spatialReference,view:this.view,layerSource:e})}:{loading:t.loader}}case"memory":case"csv":case"geojson":case"wfs":{if("mesh"===e.layer.geometryType)return null;const t=this._getSourceModule("featureCollection");return o(t.module)?{source:new t.module.FeatureCollectionSnappingSource({layerSource:e,view:this.view})}:{loading:t.loader}}}return null}_createFeatureSnappingSourceGraphicsLayer(e){const t=this._getSourceModule("graphics");return o(t.module)?{source:new t.module.GraphicsSnappingSource({getGraphicsLayers:()=>[e.layer],spatialReference:this.spatialReference,view:this.view,layerSource:e})}:{loading:t.loader}}_createFeatureSnappingSourceMapNotesLayer(e){const t=this._getSourceModule("notes");return o(t.module)?{source:new t.module.GraphicsSnappingSource({getGraphicsLayers:()=>o(e.layer.sublayers)?e.layer.sublayers.toArray():[],spatialReference:this.spatialReference,view:this.view,layerSource:e})}:{loading:t.loader}}_getSourceModule(e){const t=this._sourceModules[e];if(n(t.loader)){const r=this._loadSourceModule(e).then((e=>{t.module=e}));return t.loader=r,{module:t.module,loader:r}}return{module:t.module,loader:t.loader}}_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"))}}};e([l({constructOnly:!0})],V.prototype,"spatialReference",void 0),e([l({constructOnly:!0})],V.prototype,"view",void 0),e([l()],V.prototype,"options",void 0),e([l({readOnly:!0})],V.prototype,"updating",null),e([l({readOnly:!0})],V.prototype,"snappingSources",null),V=e([h("esri.views.interactive.snapping.FeatureSnappingEngine")],V);class I{constructor(e,t){this.snappingSource=e,this.layerView=t,this.handles=new r;const s=this.snappingSource.layerSource.layer;if("refresh"in s){const t=s;this.handles.add(t.on("refresh",(()=>e.refresh())))}this.handles.add([p((()=>e.updating),(t=>e.layerSource.updating=t),d),p((()=>e.availability),(t=>e.layerSource.availability=t),d)])}destroy(){this.snappingSource.destroy(),this.handles.destroy()}}function G(e){return(e instanceof R||e instanceof b)&&!P(e)}function P({constraint:{start:e,end:t}}){const r=m(e,t),s=g(e,t);return r<f()||s/r<A}function O(e,t,r,s,o,n,{spatialReference:a}){const i=y(z,t);i[0]+=r,i[1]+=s,i[2]+=o;const c=H(i,a,v,n);return c?x(c,e):1/0}const D=S(),z=S(),A=1e-4;export{V as FeatureSnappingEngine};