DrawOperation.js 14 KB

12345
  1. /*
  2. All material copyright ESRI, All Rights Reserved, unless otherwise specified.
  3. See https://js.arcgis.com/4.25/esri/copyright.txt for details.
  4. */
  5. import{_ as e}from"../../chunks/tslib.es6.js";import t from"../../core/Evented.js";import{HandleOwner as i}from"../../core/HandleOwner.js";import{clone as n}from"../../core/lang.js";import{isNone as r,isSome as o,destroyMaybe as s,unwrap as a,applySome as p,equalsMaybe as c}from"../../core/maybe.js";import{ignoreAbortErrors as h}from"../../core/promiseUtils.js";import{watch as d,syncAndInitial as l}from"../../core/reactiveUtils.js";import{createScreenPoint as m}from"../../core/screenUtils.js";import{property as g}from"../../core/accessorSupport/decorators/property.js";import"../../core/accessorSupport/ensureType.js";import{subclass as u}from"../../core/accessorSupport/decorators/subclass.js";import{pointEquals as v}from"../../layers/graphics/dehydratedFeatureComparison.js";import{getEffectiveElevationInfo as y}from"../../support/elevationInfoUtils.js";import{ViewingMode as _}from"../ViewingMode.js";import{defaultDrawingMode as x}from"./DrawingMode.js";import{DrawManipulator as f}from"./DrawManipulator.js";import{createCoordinateHelper as w}from"../interactive/coordinateHelper.js";import{createManipulatorDragEventPipeline as S,sceneSnappingAtLocation as V}from"../interactive/dragEventPipeline.js";import{EditGeometry as O,Component as T}from"../interactive/editGeometry/EditGeometry.js";import{EditGeometryOperations as b}from"../interactive/editGeometry/EditGeometryOperations.js";import M from"../interactive/sketch/SketchLabelOptions.js";import D from"../interactive/sketch/SketchTooltipOptions.js";import{SnappingContext as I}from"../interactive/snapping/SnappingContext.js";import{SnappingPipeline as P}from"../interactive/snapping/SnappingDragPipelineStep.js";import{SnappingOperation as E}from"../interactive/snapping/SnappingOperation.js";let C=class extends(t.EventedMixin(i)){constructor(e){super(e),this._createOperationCompleted=!1,this._pointerDownStates=new Set,this._snappingPipeline=new P,this.isDraped=!0,this.labelOptions=new M,this.tooltipOptions=new D,this.snapToSceneEnabled=null,this.lastVertex=null,r(e.elevationInfo)&&(this.elevationInfo=y(e.hasZ))}initialize(){const{geometryType:e,view:t}=this,{spatialReference:i}=t,n="viewingMode"in t.state?t.state.viewingMode:_.Local,s="segment"===e||"multipoint"===e?"polyline":e;this.coordinateHelper=w(this.hasZ,this.hasM,i),this._editGeometryOperations=new b(new O(s,this.coordinateHelper)),this._snappingOperation=new E({view:t,constrainResult:e=>r(e)?e:this._getEffectiveDrawSurface().constrainZ(e)}),this.handles.add(d((()=>this.stagedVertex),(e=>{r(e)||this.emit("cursor-update",{updated:null,vertices:[{componentIndex:0,vertexIndex:this._activeComponent.vertices.length,coordinates:this.coordinateHelper.pointToArray(e)}],operation:"apply",type:"vertex-update"})}),{sync:!0,equals:(e,t)=>c(e,t,v)})),this._activeComponent=new T(i,n),this._editGeometryOperations.data.components.push(this._activeComponent);const a=this.segmentLabels;o(a)&&(a.context={view:t,editGeometryOperations:this._editGeometryOperations,elevationInfo:this.elevationInfo,labelOptions:this.labelOptions},this.handles.add([d((()=>this.labelOptions.enabled),(e=>{a.visible=e}),l),this.on("cursor-update",(()=>{const e=this.stagedVertex;a.stagedVertex=o(e)?this.coordinateHelper.pointToVector(e):null}))])),this.handles.add(this._editGeometryOperations.on(["vertex-add","vertex-update","vertex-remove"],(e=>{const t=e.vertices.map((e=>({componentIndex:0,vertexIndex:e.index,coordinates:this.coordinateHelper.vectorToArray(e.pos)}))),i=t.map((e=>e.coordinates));switch(e.type){case"vertex-add":this.emit(e.type,{...e,added:i,vertices:t});break;case"vertex-update":this.emit(e.type,{...e,updated:i,vertices:t});break;case"vertex-remove":this.emit(e.type,{...e,removed:i,vertices:t})}const n=this._activeComponent.getLastVertex(),s=o(n)?this.coordinateHelper.vectorToDehydratedPoint(n.pos):null;(r(s)||r(this.lastVertex)||!v(this.lastVertex,s))&&(this.lastVertex=s)}))),this._manipulator=new f({grabbableForEvent:e=>"click"!==this.drawingMode||"touch"===e.pointerType&&this._snappingEnabled&&1===this._pointerDownStates.size}),this.manipulators.add(this._manipulator),this._manipulator.grabbable="point"!==e,this.handles.add([this._createManipulatorDragPipeline(this._manipulator),this._manipulator.events.on("immediate-click",(e=>this._onImmediateClick(e))),this._manipulator.events.on("immediate-double-click",(e=>this._onImmediateDoubleClick(e)))])}destroy(){s(this.segmentLabels),s(this._snappingOperation),this._editGeometryOperations=s(this._editGeometryOperations)}get _snappingEnabled(){return o(this.snappingManager)&&this.snappingManager.options.effectiveEnabled}get _requiresScenePoint(){const e=this._getEffectiveDrawSurface();return"3d"===this.view.type&&this.drawSurface!==e}get canRedo(){return this._editGeometryOperations.canRedo}get canUndo(){return this._editGeometryOperations.canUndo}get committedVertices(){return this._activeComponent.vertices.map((e=>this.coordinateHelper.vectorToArray(e.pos)))}set drawingMode(e){this._set("drawingMode",e??x)}get interactive(){return this._manipulator.interactive}set interactive(e){this._manipulator.interactive=e}get isCompleted(){return this._createOperationCompleted}get numCommittedVertices(){return this._activeComponent.vertices.length}get numVertices(){return o(this.stagedVertex)?this._activeComponent.vertices.length+1:this._activeComponent.vertices.length}get stagedVertex(){return this._snappingOperation.stagedPoint}set stagedVertex(e){this._snappingOperation.stagedPoint=n(e)}get updating(){return this.updatingHandles.updating}get vertices(){const e=this.committedVertices;return o(this.stagedVertex)&&e.push(this.coordinateHelper.pointToArray(this.stagedVertex)),e}cancel(){this.complete({aborted:!0})}commitStagedVertex(){if(this._snappingOperation.abort(),o(this.stagedVertex)){const{stagedVertex:e}=this;this.stagedVertex=null,this._editGeometryOperations.appendVertex(this.coordinateHelper.pointToVector(e))}}complete(e){const t=e&&e.aborted||!1;this._snappingOperation.abort(),o(this.snappingManager)&&this.snappingManager.doneSnapping(),"segment"===this.geometryType||"point"===this.geometryType?this.commitStagedVertex():this.stagedVertex=null;const i="multipoint"===this.geometryType&&0===this.numVertices||"polyline"===this.geometryType&&this.numVertices<2||"polygon"===this.geometryType&&this.numVertices<3;this._createOperationCompleted=!i,(this.isCompleted||t)&&this.emit("complete",{vertices:this.vertices.map(((e,t)=>({componentIndex:0,vertexIndex:t,coordinates:e}))),aborted:t,type:"complete"})}onInputEvent(e){switch(e.type){case"pointer-down":this._pointerDownStates.add(e.pointerId);break;case"pointer-up":this._pointerDownStates.delete(e.pointerId)}switch(e.type){case"pointer-move":return this._onPointerMove(e);case"hold":return this._onHold(e)}}redo(){this._editGeometryOperations.redo()}undo(){o(this.snappingManager)&&this.snappingManager.doneSnapping(),this._editGeometryOperations.undo()}_closeOnClickVertexIndex(e){const t=this._activeComponent;if("polygon"===this.geometryType&&t.vertices.length>2){if(this._vertexWithinPointerDistance(t.vertices[0].pos,e))return 0;if(this._vertexWithinPointerDistance(t.vertices[t.vertices.length-1].pos,e))return t.vertices.length-1}return null}_createManipulatorDragPipeline(e){switch(a(this.drawingMode)){case"click":return this._createManipulatorDragPipelineClick(e);case"freehand":return this._createManipulatorDragPipelineFreehand(e);case"hybrid":return this._createManipulatorDragPipelineHybrid(e)}}_createManipulatorDragPipelineClick(e){return S(e,((e,t,i,n)=>{const r="touch"===n&&this._snappingEnabled;!this.isCompleted&&r&&(i=i.next((e=>(r&&o(this.snappingManager)&&this.snappingManager.doneSnapping(),e))),t.next(this._screenToMapDragEventStep()).next((e=>("start"===e.action&&(this.stagedVertex=e.mapStart,("segment"===this.geometryType||r&&0===this.numVertices)&&this.commitStagedVertex()),e))).next(V(this.view,this.elevationInfo)).next(this._snappingPipeline.createSnapDragEventPipelineStep({predicate:()=>r,cancel:i,snappingManager:this.snappingManager,snappingContext:new I({editGeometryOperations:this._editGeometryOperations,elevationInfo:this.elevationInfo,pointer:n,visualizer:this.snappingVisualizer}),updatingHandles:this.updatingHandles,useZ:!this._requiresScenePoint}),this._snappingPipeline.next).next((e=>(r&&(this.stagedVertex=e.mapEnd,"end"===e.action&&this.commitStagedVertex()),e))).next((e=>("end"===e.action&&("segment"!==this.geometryType&&"point"!==this.geometryType||this.complete()),e))))}))}_createManipulatorDragPipelineFreehand(e){return S(e,((e,t)=>{this.isCompleted||t.next(this._screenToMapDragEventStep()).next((e=>("start"===e.action&&(r(this.stagedVertex)&&(this.stagedVertex=e.mapStart),"segment"===this.geometryType&&this.commitStagedVertex()),e))).next((e=>{switch(e.action){case"start":case"update":this.stagedVertex=e.mapEnd,"polygon"!==this.geometryType&&"polyline"!==this.geometryType||this.commitStagedVertex();break;case"end":this.complete()}return e}))}))}_createManipulatorDragPipelineHybrid(e){return S(e,((e,t)=>{this.isCompleted||t.next(this._screenToMapDragEventStep()).next((e=>("start"===e.action&&(r(this.stagedVertex)&&(this.stagedVertex=e.mapStart),this.commitStagedVertex()),e))).next((e=>{switch(e.action){case"start":case"update":this.stagedVertex=e.mapEnd,"polygon"!==this.geometryType&&"polyline"!==this.geometryType||this.commitStagedVertex();break;case"end":"segment"!==this.geometryType&&"point"!==this.geometryType||this.complete()}return e}))}))}get _drawAtFixedElevation(){return("segment"===this.geometryType||"polygon"===this.geometryType)&&this.numCommittedVertices>0}_getEffectiveDrawSurface(){if(r(this.elevationDrawSurface))return this.drawSurface;if(!this.coordinateHelper.hasZ())return this.elevationDrawSurface.defaultZ=null,this.elevationDrawSurface;let e=this.defaultZ,t=!1;return o(this.elevationInfo)&&"absolute-height"===this.elevationInfo.mode&&(t=!0),o(this.snapToSceneEnabled)&&(t=this.snapToSceneEnabled),o(this.elevationInfo)&&"on-the-ground"===this.elevationInfo.mode&&(t=!1),this._drawAtFixedElevation&&(e=this.coordinateHelper.getZ(this._activeComponent.vertices[0].pos),t=!1),t?this.drawSurface:(this.elevationDrawSurface.defaultZ=e,this.elevationDrawSurface)}_mapToScreen(e){return this._getEffectiveDrawSurface().mapToScreen(e)}_onHold(e){this._snappingOperation.abort(),"click"===this.drawingMode&&"touch"===e.pointerType&&this._snappingEnabled&&(this.stagedVertex=e.mapPoint),e.stopPropagation()}_onImmediateClick(e){if("mouse"===e.pointerType&&2===e.button||this._manipulator.dragging)return;const t=this._activeComponent,i=this._closeOnClickVertexIndex(e.screenPoint);if(o(i))return e.stopPropagation(),void this.complete();const n=this._screenToMap(e.screenPoint);if(o(n))switch(this.drawingMode){case"freehand":"point"===this.geometryType&&(o(this.stagedVertex)?this.commitStagedVertex():this._editGeometryOperations.appendVertex(this.coordinateHelper.pointToVector(n)),this.complete());break;case"click":case"hybrid":this._snappingOperation.abort(),o(this.stagedVertex)?this.commitStagedVertex():this._editGeometryOperations.appendVertex(this.coordinateHelper.pointToVector(n)),("point"===this.geometryType||"segment"===this.geometryType&&2===t.vertices.length||"segment"===this.geometryType&&"hybrid"===this.drawingMode&&1===t.vertices.length)&&this.complete()}e.stopPropagation()}_onImmediateDoubleClick(e){this._manipulator.dragging||"point"===this.geometryType||(this.complete(),e.stopPropagation())}_onPointerMove(e){const t=m(e.x,e.y),i=this._snappingOperation;if(this._manipulator.dragging||this._pointerDownStates.has(e.pointerId)||this._manipulator.grabbing||!this._manipulator.interactive)return void i.abort();e.stopPropagation();const n=this._closeOnClickVertexIndex(t);if(o(n))return this._closeOnVertex(n),void i.abort();const s=this._screenToMap(t),a=this._requiresScenePoint?this.drawSurface.screenToMap(t):null;if(this._manipulator.cursor=o(s)?"crosshair":null,r(s))return void i.abort();const c=this.snappingManager;if(r(c))return this.stagedVertex=s,void i.abort();const d=this._drawAtFixedElevation?p(this.elevationDrawSurface,(({defaultZ:e})=>e)):null,l=new I({editGeometryOperations:this._editGeometryOperations,elevationInfo:this.elevationInfo,pointer:e.pointerType,visualizer:this.snappingVisualizer,selfSnappingZ:o(d)?{value:d,elevationInfo:this.elevationInfo}:null});this.updatingHandles.addPromise(h(i.snap({point:s,scenePoint:a},c,l)))}_closeOnVertex(e){this.stagedVertex=null;const t={componentIndex:0,vertexIndex:e,coordinates:this.coordinateHelper.vectorToArray(this._activeComponent.vertices[e].pos)};this.emit("cursor-update",{updated:null,vertices:[t],operation:"apply",type:"vertex-update"})}_screenToMap(e){return this._getEffectiveDrawSurface().screenToMap(e)}_screenToMapDragEventStep(){let e=null;return t=>{if("start"===t.action&&(e=this._screenToMap(t.screenStart)),r(e))return null;const i=this._screenToMap(t.screenEnd);return o(i)?{...t,mapStart:e,mapEnd:i}:null}}_vertexWithinPointerDistance(e,t){const i=25,n=this._mapToScreen(this.coordinateHelper.vectorToDehydratedPoint(e));return!!o(n)&&k(n,t,i)}};function k(e,t,i){const n=e.x-t.x,r=e.y-t.y;return n*n+r*r<=i}e([g()],C.prototype,"_snappingEnabled",null),e([g()],C.prototype,"defaultZ",void 0),e([g()],C.prototype,"isDraped",void 0),e([g({value:x})],C.prototype,"drawingMode",null),e([g({constructOnly:!0})],C.prototype,"elevationDrawSurface",void 0),e([g({constructOnly:!0})],C.prototype,"elevationInfo",void 0),e([g({constructOnly:!0,type:M})],C.prototype,"labelOptions",void 0),e([g({constructOnly:!0,type:D})],C.prototype,"tooltipOptions",void 0),e([g({constructOnly:!0})],C.prototype,"geometryType",void 0),e([g({constructOnly:!0})],C.prototype,"hasM",void 0),e([g({constructOnly:!0})],C.prototype,"hasZ",void 0),e([g({constructOnly:!0})],C.prototype,"manipulators",void 0),e([g({constructOnly:!0})],C.prototype,"drawSurface",void 0),e([g({constructOnly:!0})],C.prototype,"segmentLabels",void 0),e([g({constructOnly:!0})],C.prototype,"snappingManager",void 0),e([g({constructOnly:!0})],C.prototype,"snappingVisualizer",void 0),e([g()],C.prototype,"snapToSceneEnabled",void 0),e([g()],C.prototype,"_snappingOperation",void 0),e([g()],C.prototype,"stagedVertex",null),e([g()],C.prototype,"lastVertex",void 0),e([g()],C.prototype,"updating",null),e([g({constructOnly:!0})],C.prototype,"view",void 0),C=e([u("esri.views.draw.DrawOperation")],C);export{C as DrawOperation};