UNPKG

@arcgis/core

Version:

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

6 lines (5 loc) • 14.2 kB
/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.32/esri/copyright.txt for details. */ import{_ as e}from"../../../../chunks/tslib.es6.js";import{updatePointsFromFeatureReference as t,getFeatureId as o}from"../../../../analysis/featureReferenceUtils.js";import i from"../../../../core/Accessor.js";import{createTask as n}from"../../../../core/asyncUtils.js";import r from"../../../../core/Evented.js";import s from"../../../../core/Handles.js";import{handlesGroup as a,makeHandle as l}from"../../../../core/handleUtils.js";import c from"../../../../core/Logger.js";import{abortMaybe as u}from"../../../../core/maybe.js";import{ignoreAbortErrors as d}from"../../../../core/promiseUtils.js";import{initial as p}from"../../../../core/reactiveUtils.js";import{property as g}from"../../../../core/accessorSupport/decorators/property.js";import"../../../../core/has.js";import"../../../../core/RandomLCG.js";import{subclass as h}from"../../../../core/accessorSupport/decorators/subclass.js";import{c as m,d as v,n as f,h as _,g as b,G as y,a as C}from"../../../../chunks/vec32.js";import{create as T}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{UpdatingHandles as O}from"../../../../core/support/UpdatingHandles.js";import I from"../../../../geometry/Point.js";import{projectOrLoad as P}from"../../../../geometry/projection.js";import{projectBoundingRect as j}from"../../../../geometry/projection/projectBoundingRect.js";import{empty as S,containsPointObject as w,intersectsSegment as R}from"../../../../geometry/support/aaBoundingRect.js";import{fromPoints as A,create as H}from"../../../../geometry/support/ray.js";import{zValueInAbsoluteHeightMode as E}from"../../../../support/elevationInfoUtils.js";import L from"../LineOfSightAnalysisResult.js";import{LineOfSightComputation as V}from"./LineOfSightComputation.js";import{LineOfSightRayIntersector as F}from"./LineOfSightRayIntersector.js";import{logFailedGeometryProjectionError as x}from"../support/projectionUtils.js";import{StoreResults as D}from"../../webgl-engine/lib/IntersectorInterfaces.js";import{toGraphic as G}from"../../webgl-engine/lib/intersectorUtilsConversions.js";import{ImmediateTask as N,TaskPriority as z}from"../../../support/Scheduler.js";let k=class extends(r.EventedMixin(i)){constructor(e){super(e),this.updateOnCameraChange=!0,this._observerGroundOffsetRenderSpace=0,this._effectiveObserverElevationMode="absolute-height",this._observerFeatureId=null,this._updatingHandles=new O,this._frameTask=N,this._computationHandles=new s,this._externalObserverUpdate=!0}initialize(){const e=this.view.resourceController?.scheduler;this._frameTask=e?e.registerTask(z.LINE_OF_SIGHT_TOOL):N,this._intersector=new F({view:this.view}),this.addHandles([this._connectObserver(),this._connectComputations(),this._connectTargets()])}destroy(){this._computationHandles.destroy(),this._computations.removeAll(),this._updatingHandles.destroy()}get updating(){return this._frameTask.updating||this._updatingHandles.updating}get priority(){return this._frameTask.priority}set priority(e){this._frameTask.priority=e}get _computations(){return this.analysisViewData.computations}get _elevationAlignedObserverPositionRenderSpace(){return this.analysisViewData.observerEngineLocation}set _elevationAlignedObserverPositionRenderSpace(e){this.analysisViewData.observerEngineLocation=e}get _screenPixelSize(){return this.view.state.camera.computeScreenPixelSizeAt(this._elevationAlignedObserverPositionRenderSpace)}_computeResult(e){const t=e.computation,{inputPoints:o,computationResult:i}=t,{observerAdjusted:n,targetAdjusted:r}=o,{start:s,end:a}=i;m(s,n),m(a,r);this._canCompute(t)?this._computeIntersection(e):M(e),t.notifyResultChanged(),this.emit("result-changed",{target:e.computation.target,result:t.result})}_adjustStartEndPositions(e){const{view:o}=this,{inputPoints:i}=e,{observer:n,target:r,observerAdjusted:s,targetAdjusted:a}=i;m(s,n),m(a,r),t(o,this._intersector.intersector,i);const{observerSurfaceNormal:l,targetSurfaceNormal:c}=i,u=this._screenPixelSize,d=B;null!=l?m(d,l):v(d,a,s);const p=u;f(d,d),_(d,d,Math.min(p,1)),b(s,s,d),null!=c?m(d,c):v(d,s,a);const g=o.state.camera.computeScreenPixelSizeAt(a);f(d,d),_(d,d,Math.min(g,1)),b(a,a,d)}_computeIntersection({computation:e,interpolationInfo:t}){const{view:o}=this,{sceneIntersectionHelper:i,renderCoordsHelper:n}=o;if(null==i)return;const r=this._intersector.intersector,{computationResult:s,inputPoints:a}=e,{observer:l,target:c}=a,{start:u,end:d}=s,p=A(u,d,q);r.options.store=D.MIN,i.intersectToolIntersectorRay(p,r);const g=r.results.min,h=s.intersection,v=B;let f=!0;if(null!=g&&g.getIntersectionPoint(h)){m(t.originalIntersection,h),m(t.originalObserver,u),m(t.originalTarget,d),n.fromRenderCoords(h,v,o.spatialReference);const e=1-y(d,c)/y(u,c);f=y(l,h)>=e*y(l,c)}const _=new I(v,o.spatialReference);{const{result:t,target:i}=e;null!=t?(t.target=i,t.intersectedGraphic=f?null:G(g,o),t.intersectedLocation=f?null:_,t.visible=f):e.result=new L({target:i,elevationAlignedTargetLocation:e.elevationAlignedTargetLocation,intersectedGraphic:f?null:G(g,o),intersectedLocation:f?null:_,visible:f})}s.isValid=a.isValid=!0,s.isTargetVisible=f}_canCompute(e){const t=this.analysisViewData.elevationAlignedObserver,o=this.view.frustum;if(null==t||null==e.elevationAlignedTargetLocation||null==o)return!1;const{observerAdjusted:i,targetAdjusted:n}=e.inputPoints,r=o.intersectsPoint(i),s=o.intersectsPoint(n);return r&&s}_onObserverPositionChange(e,t,i,n,r){if(this._externalObserverUpdate=r,null==e)return this.analysisViewData.elevationAlignedObserver=null,void(this._observerFeatureId=null);if(null==t)return x(this.analysis,e.spatialReference,c.getLogger(this)),void(this.analysisViewData.elevationAlignedObserver=null);const s=U(t,i),{absoluteZ:a,elevation:l}=E(t.x,t.y,t.z,this.view.spatialReference,this.view,s),u=t.clone();u.z=a,this._effectiveObserverElevationMode=s.mode,this.analysisViewData.elevationAlignedObserver=u;const d=T();this.view.renderCoordsHelper.toRenderCoords(u,d),this._elevationAlignedObserverPositionRenderSpace=d,this._observerGroundOffsetRenderSpace=a-l,this._observerFeatureId=o(n),this.priority=z.LINE_OF_SIGHT_TOOL_INTERACTIVE}_onObserverRenderSpacePositionChangeForComputation(e,t,o,i,n){const{inputPoints:r}=e;switch(m(r.observer,t),r.observerFeatureId=n,r.observerSurfaceNormal=null,i){case"on-the-ground":case"relative-to-ground":{const e=this._intersector.updateFromGroundIntersection(r.observer,o,r.observer);null==r.observerFeatureId&&(r.observerSurfaceNormal=e)}}this._adjustStartEndPositions(e),e.notifyInputPointsChanged(),this.priority=z.LINE_OF_SIGHT_TOOL_INTERACTIVE}_onTargetPositionChange(e,t,i,n,r,s=!0){const a=e.inputPoints;if(s&&(a.isValid=!1),null==i)return null!=t&&x(this.analysis,t.spatialReference,c.getLogger(this)),e.elevationAlignedTargetLocation=null,void e.notifyInputPointsChanged();const l=U(i,n),{absoluteZ:u,elevation:d}=E(i.x,i.y,i.z,this.view.spatialReference,this.view,l),p=i.clone();switch(p.z=u,e.elevationAlignedTargetLocation=p,this.view.renderCoordsHelper.toRenderCoords(e.elevationAlignedTargetLocation,a.target),a.targetFeatureId=o(r),a.targetSurfaceNormal=null,l.mode){case"on-the-ground":case"relative-to-ground":{const e=this._intersector.updateFromGroundIntersection(a.target,u-d,a.target);null==a.targetFeatureId&&(a.targetSurfaceNormal=e)}}this._adjustStartEndPositions(e),e.notifyInputPointsChanged(),this.priority=z.LINE_OF_SIGHT_TOOL_INTERACTIVE}_connectComputationToTarget(e){return a([this._updatingHandles.add((()=>({computation:e,targetPosition:e.target.position,targetElevationInfo:e.target.elevationInfo,targetFeatureInfo:e.target.feature,projectedTargetPosition:P(e.target.position,this.view.spatialReference)})),(({computation:e,targetPosition:t,targetElevationInfo:o,targetFeatureInfo:i,projectedTargetPosition:n})=>{null==n.pending?this._onTargetPositionChange(e,t,n.geometry,o,i):this._updatingHandles.addPromise(n.pending)}),p)])}_connectComputationToObserver(e){return this._updatingHandles.add((()=>({computation:e,observer:this.analysisViewData.elevationAlignedObserver})),(({computation:e})=>{this._externalObserverUpdate&&(e.inputPoints.isValid=!1,e.notifyInputPointsChanged())}),p)}_connectComputationToRenderSpaceObserver(e){return this._updatingHandles.add((()=>({computation:e,observer:this._elevationAlignedObserverPositionRenderSpace,observerGroundOffset:this._observerGroundOffsetRenderSpace,observerElevationMode:this._effectiveObserverElevationMode,observerFeatureId:this._observerFeatureId})),(({computation:e,observer:t,observerGroundOffset:o,observerElevationMode:i,observerFeatureId:n})=>{this._onObserverRenderSpacePositionChangeForComputation(e,t,o,i,n)}),p)}_connectComputationToCamera(e){return this._updatingHandles.add((()=>({camera:this.view.state.camera,isDirty:this._isCameraDirty})),(({isDirty:t})=>{!this.updateOnCameraChange||e.inputPoints.isValid&&!t||e.notifyInputPointsChanged()}))}_connectComputationToSlicePlane(e){return this._updatingHandles.add((()=>this.view.slicePlane),(()=>{e.inputPoints.isValid=!1,e.notifyInputPointsChanged()}))}_connectComputationToElevation(e){const t=(o,i)=>{const n=this.analysis.observer,r=e.target;let s=null,a=null,l=null,c=null,u=null,d=null;if(null!=n?.position){const e=P(n.position,this.view.spatialReference);if(null!=e.pending)return this._updatingHandles.addPromise(e.pending),void e.pending.finally((()=>t(o,i)));s=e.geometry,a=n.elevationInfo,l=n.feature}if(null!=r.position){const e=P(r.position,this.view.spatialReference);if(null!=e.pending)return this._updatingHandles.addPromise(e.pending),void e.pending.finally((()=>t(o,i)));c=e.geometry,u=r.elevationInfo,d=r.feature}null==s&&null==c||(j(o,i,J,this.view.spatialReference),null!=s&&w(J,s)&&this._onObserverPositionChange(null!=n?n.position:null,s,a,l,!1),null!=c&&w(J,c)&&this._onTargetPositionChange(e,r.position,c,u,d,!1),null!=s&&null!=c&&R(J,s,c)&&e.notifyInputPointsChanged())};return this.view.elevationProvider.on("elevation-change",(({extent:e,spatialReference:o})=>t(e,o)))}_connectComputationToTask(e){let t=null;const o={computation:e,interpolationInfo:{originalIntersection:T(),originalObserver:T(),originalTarget:T()}};return a([this._updatingHandles.add((()=>e.inputPoints),(()=>{t=u(t),t=n((async e=>{await d(this._frameTask.schedule((()=>this._computeResult(o)),e))}))}),{initial:!0,equals:()=>!1}),l((()=>t=u(t)))])}_connectComputation(e){const t=this._computationHandles;t.has(e)||t.add([this._connectComputationToTarget(e),this._connectComputationToObserver(e),this._connectComputationToRenderSpaceObserver(e),this._connectComputationToCamera(e),this._connectComputationToSlicePlane(e),this._connectComputationToElevation(e),this._connectComputationToTask(e)],e)}_disconnectComputation(e){this._computationHandles.remove(e)}_onComputationCollectionChange({added:e,removed:t}){for(const o of t)this._disconnectComputation(o);for(const o of e)this._connectComputation(o)}_onTargetCollectionChange({added:e,removed:t}){for(const o of t)this._removeTarget(o);for(const o of e)this._addTarget(o)}_onCursorTargetChange(e,t){null!=t&&this._removeTarget(t),null!=e&&this._addTarget(e)}_addTarget(e){this._computations.some((t=>t.target===e))||this._computations.add(new V({target:e}))}_removeTarget(e){const t=this._computations.findIndex((t=>t.target===e));this._computations.removeAt(t)}_connectObserver(){return a([this._updatingHandles.add((()=>({observerPosition:null!=this.analysis.observer?this.analysis.observer.position:null,projectedObserverPosition:P(null!=this.analysis.observer?this.analysis.observer.position:null,this.view.spatialReference),observerElevationInfo:null!=this.analysis.observer?this.analysis.observer.elevationInfo:null,observerFeatureInfo:null!=this.analysis.observer?this.analysis.observer.feature:null})),(({observerPosition:e,projectedObserverPosition:t,observerElevationInfo:o,observerFeatureInfo:i})=>{null==t.pending?this._onObserverPositionChange(e,t.geometry,o,i,!0):this._updatingHandles.addPromise(t.pending)}),p)])}_connectComputations(){return this._updatingHandles.addOnCollectionChange((()=>this._computations),(e=>this._onComputationCollectionChange(e)),{initial:!0,final:!0})}_connectTargets(){return a([this._updatingHandles.addOnCollectionChange((()=>this.analysis.targets),(e=>this._onTargetCollectionChange(e)),{initial:!0,final:!0}),this._updatingHandles.add((()=>this.analysisViewData.cursorTarget),((e,t)=>{this._onCursorTargetChange(e,t)}))])}get _isCameraDirty(){const e=this.analysisViewData.elevationAlignedObserver,{view:t}=this,{renderCoordsHelper:o}=t;if(null==e||null==o)return!1;const i=B;o.toRenderCoords(e,i);const n=t.state.camera.computeScreenPixelSizeAt(i);return Math.abs((n-this._screenPixelSize)/this._screenPixelSize)>Z}};function U(e,t){return e.hasZ?t??{mode:"absolute-height",offset:0}:{mode:"on-the-ground",offset:0}}function M({computation:e,interpolationInfo:t}){const{computationResult:o,inputPoints:i}=e,{start:n,end:r,intersection:s}=o,{originalIntersection:a,originalObserver:l,originalTarget:c}=t;if(m(s,a),i.isValid){const e=B,t=y(l,a)/y(l,c);C(e,n,l),_(e,e,1-t),b(s,s,e),C(e,r,c),_(e,e,t),b(s,s,e),o.isValid=!0}else e.result=null,o.isValid=!1,o.isTargetVisible=!1}e([g({constructOnly:!0})],k.prototype,"analysis",void 0),e([g({constructOnly:!0})],k.prototype,"analysisViewData",void 0),e([g({constructOnly:!0})],k.prototype,"view",void 0),e([g()],k.prototype,"updating",null),e([g()],k.prototype,"priority",null),e([g()],k.prototype,"updateOnCameraChange",void 0),e([g()],k.prototype,"_computations",null),e([g()],k.prototype,"_elevationAlignedObserverPositionRenderSpace",null),e([g()],k.prototype,"_observerGroundOffsetRenderSpace",void 0),e([g()],k.prototype,"_effectiveObserverElevationMode",void 0),e([g()],k.prototype,"_observerFeatureId",void 0),e([g()],k.prototype,"_screenPixelSize",null),e([g({readOnly:!0})],k.prototype,"_updatingHandles",void 0),e([g()],k.prototype,"_frameTask",void 0),e([g()],k.prototype,"_isCameraDirty",null),k=e([h("esri.views.3d.analysis.LineOfSight.LineOfSightController")],k);const Z=.1,B=T(),q=H(),J=S();export{k as LineOfSightController};