@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 18.9 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 t}from"../../chunks/tslib.es6.js";import e from"../../core/Accessor.js";import i from"../../core/Evented.js";import{clone as n}from"../../core/lang.js";import{equalsMaybe as o,destroyMaybe as r}from"../../core/maybe.js";import{memoize as s}from"../../core/memoize.js";import{ignoreAbortErrors as a}from"../../core/promiseUtils.js";import p from"../../core/ReactiveSet.js";import{watch as c,syncAndInitial as l}from"../../core/reactiveUtils.js";import{createScreenPoint as d}from"../../core/screenUtils.js";import{property as h}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{diff as m}from"../../core/accessorSupport/diffUtils.js";import{UpdatingHandles as g}from"../../core/support/UpdatingHandles.js";import{pointEquals as y,pointNear as _}from"../../layers/graphics/dehydratedFeatureComparison.js";import{getEffectiveElevationInfo as v}from"../../support/elevationInfoUtils.js";import{ViewingMode as f}from"../ViewingMode.js";import{defaultDrawingMode as x}from"./DrawingMode.js";import{DrawManipulator as C}from"./DrawManipulator.js";import{createCoordinateHelper as b}from"../interactive/coordinateHelper.js";import{createManipulatorDragEventPipeline as T,sceneSnappingAtLocation as S}from"../interactive/dragEventPipeline.js";import{EditGeometry as P,Component as V}from"../interactive/editGeometry/EditGeometry.js";import{EditGeometryOperations as w}from"../interactive/editGeometry/EditGeometryOperations.js";import{isPoint as O}from"../interactive/sketch/constraints.js";import{getPointConstraint as M,getPolylineOrPolygonConstraint as D,pointToConstraintSpace as E,constraintSpaceToPoint as I}from"../interactive/sketch/constraintUtils.js";import H from"../interactive/sketch/SketchLabelOptions.js";import{SnappingContext as j}from"../interactive/snapping/SnappingContext.js";import{createSnapDragEventPipelineStep as G}from"../interactive/snapping/SnappingDragPipelineStep.js";import{SnappingOperation as k}from"../interactive/snapping/SnappingOperation.js";import{setupSnappingToggleHandles as Z}from"../interactive/snapping/snappingUtils.js";const L="crosshair",U="progress",A=Symbol(),z=Symbol();let F=class extends(i.EventedMixin(e)){constructor(t){super(t),this._createOperationCompleted=!1,this._hideDefaultCursor=!1,this._pointerDownStates=new p,this._stagedScreenPoint=null,this._stagedPointerType=null,this._updatingHandles=new g,this._stagedPointerId=null,this.constraintsEnabled=!1,this.constraints=void 0,this._getPointConstraint=s(M),this._getPolylineOrPolygonConstraint=s(D),this.constraintZ=null,this.defaultZ=null,this.isDraped=!0,this.labelOptions=new H,this.cursor=null,this.loading=!1,this.snapToSceneEnabled=null,this.firstVertex=null,this.lastVertex=null,this.secondToLastVertex=null,null==t.elevationInfo&&(this.elevationInfo=v(!!t.hasZ))}initialize(){const{geometryType:t,view:e}=this,i=e.spatialReference,n="viewingMode"in e.state?e.state.viewingMode:f.Local,r="segment"===t||"multipoint"===t?"polyline":t;this.coordinateHelper=b(this.hasZ,this.hasM,i),this._editGeometryOperations=new w(new P(r,this.coordinateHelper),n),this._snappingOperation=new k({view:e}),this.addHandles([c((()=>({stagedPoint:this._snappingOperation.stagedPoint,constraint:this._constraint})),(({stagedPoint:t,constraint:e},i)=>{const{snappingOptions:n}=this;n&&(n.forceDisabled=null!=e&&O(e));if(null!=i&&t===i.stagedPoint&&e!==i.constraint)return this._onKeyboardBasedChange();this._processCursor(t??this._screenToMap(this._stagedScreenPoint))}),{equals:(t,e)=>t.stagedPoint===e.stagedPoint&&o(t.constraint,e.constraint)}),c((()=>this.view.viewpoint),((t,e)=>{t&&e&&m(t,e)&&this._onKeyboardBasedChange()}))]),this._activeComponent=new V(i,n),this._editGeometryOperations.data.components.push(this._activeComponent);const s=this.segmentLabels;null!=s&&(s.context={view:e,editGeometryOperations:this._editGeometryOperations,elevationInfo:this.elevationInfo,labelOptions:this.labelOptions,automaticLengthMeasurementUtils:this.automaticLengthMeasurementUtils},this.addHandles(c((()=>this.labelOptions.enabled),(t=>{s.visible=t}),l))),this.addHandles(this._editGeometryOperations.on(["vertex-add","vertex-update","vertex-remove"],(t=>{const e=t.vertices.map((t=>({componentIndex:0,vertexIndex:t.index,coordinates:this.coordinateHelper.vectorToArray(t.pos)}))),i=e.map((t=>t.coordinates)),n=this.coordinateHelper.vectorToDehydratedPoint(this._activeComponent.getFirstVertex()?.pos)??null;y(n,this.firstVertex)||(this.firstVertex=n);const o=this.coordinateHelper.vectorToDehydratedPoint(this._activeComponent.getLastVertex()?.pos)??null;y(o,this.lastVertex)||(this.lastVertex=o);const r=this.coordinateHelper.vectorToDehydratedPoint(this._activeComponent.edges.at(-1)?.leftVertex?.pos)??null;switch(y(r,this.secondToLastVertex)||(this.secondToLastVertex=r),this._processCursor(this.cursorVertex),t.type){case"vertex-add":this.emit(t.type,{...t,added:i,vertices:e});break;case"vertex-update":this.emit(t.type,{...t,updated:i,vertices:e});break;case"vertex-remove":this.emit(t.type,{...t,removed:i,vertices:e})}})));const p=this._manipulator=new C({consumesClicks:!1,grabbableForEvent:t=>"click"!==this.drawingMode||"touch"===t.pointerType&&this._snappingEnabled&&1===this._pointerDownStates.size});this.manipulators.add(p),p.grabbable="point"!==t&&"multipoint"!==t,this.addHandles([p.events.on("immediate-click",(t=>this._onImmediateClick(t))),p.events.on("immediate-double-click",(t=>this._onImmediateDoubleClick(t))),c((()=>this.drawingMode),(()=>{this.removeHandles(A),this.addHandles(this._createManipulatorDragPipeline(p),A)}),l),c((()=>({effectiveCursor:this.effectiveCursor})),(({effectiveCursor:t})=>{p.cursor=t}),l)]),Z(this,(()=>{const t=this.view.inputManager.latestPointerType??"mouse",e=this._getSnappingContext(t);if(null!=this.snappingManager){const t=this._snappingOperation.snapAgainNearPreviousMapPoint(this.snappingManager,e);this._updatingHandles.addPromise(a(t))}}))}destroy(){r(this.segmentLabels),r(this._snappingOperation),this._editGeometryOperations=r(this._editGeometryOperations),this._updatingHandles.destroy()}get _isDragging(){const{_stagedPointerId:t,_manipulator:e}=this;return null!=t&&this._pointerDownStates.has(t)||e.grabbing||!e.interactive}get _snappingEnabled(){return null!=this.snappingManager&&this.snappingManager.options.effectiveEnabled}get _requiresScenePoint(){const t=this._updateAndGetEffectiveDrawSurface();return"3d"===this.view.type&&this.drawSurface!==t}get canRedo(){return this._editGeometryOperations.canRedo}get canUndo(){return this._editGeometryOperations.canUndo}get committedVertices(){return this._activeComponent.vertices.map((t=>this.coordinateHelper.vectorToArray(t.pos)))}get _constraint(){const{constraints:t,constraintsEnabled:e}=this;if(t&&e)switch(this.geometryType){case"point":case"multipoint":return this._getPointConstraint(t);case"polygon":case"polyline":return this._getPolylineOrPolygonConstraint(this.lastVertex,this.secondToLastVertex,t)}}set drawingMode(t){this._set("drawingMode",t??x)}get effectiveCursor(){return this.loading?U:this._hideDefaultCursor?null:this.cursor||L}get interactive(){return this._manipulator.interactive}set interactive(t){this._manipulator.interactive=t}get isCompleted(){return this._createOperationCompleted}get numCommittedVertices(){return this._activeComponent.vertices.length}get snappingOptions(){return null!=this.snappingManager?this.snappingManager.options:null}get cursorVertex(){return this._get("cursorVertex")}get visualizationCursorVertex(){return"mouse"===this._stagedPointerType?this.cursorVertex:null}get committableVertex(){const{cursorVertex:t,lastVertex:e,firstVertex:i,geometryType:n}=this;return"polygon"===n&&_(t,i)||_(t,e)?null:t}get updating(){return this._updatingHandles.updating}get geometryIncludingUncommittedVertices(){const{committedVertices:t,committableVertex:e,coordinateHelper:i}=this,n=t.slice();return null!=e&&n.push(i.pointToArray(e)),n}cancel(){this.complete({aborted:!0})}commitStagedVertex(){this._snappingOperation.abort();const{committableVertex:t}=this;null!=t&&this._editGeometryOperations.appendVertex(this.coordinateHelper.pointToVector(t))}complete(t){const e=t?.aborted||!1;this._snappingOperation.abort(),this.snappingManager?.doneSnapping();const{geometryType:i,numCommittedVertices:n}=this,o="multipoint"===i&&0===n||"polyline"===i&&n<2||"polygon"===i&&n<3;"segment"!==i&&"point"!==i||this.commitStagedVertex(),this._createOperationCompleted=!o,(this.isCompleted||e)&&(this._stagedScreenPoint=null,this._stagedPointerId=null,this._stagedPointerType=null,this._processCursor(null),this.emit("complete",{vertices:this.committedVertices.map(((t,e)=>({componentIndex:0,vertexIndex:e,coordinates:t}))),aborted:e,type:"complete"}))}onInputEvent(t){switch(t.type){case"pointer-down":this._pointerDownStates.add(t.pointerId);break;case"pointer-up":this._pointerDownStates.delete(t.pointerId)}switch(t.type){case"pointer-move":return this._onPointerMove(t);case"hold":return this._onHold(t)}}redo(){this._editGeometryOperations.redo()}undo(){null!=this.snappingManager&&this.snappingManager.doneSnapping(),this._editGeometryOperations.undo()}_processCursor(t){const e=n(this.cursorVertex),i=n(t),o=i&&(this._updateAndGetEffectiveDrawSurface()?.constrainZ(i)??i),r=this._snapToClosingVertex(o),s=this._applyConstraints(r);_(e,s)||(this._set("cursorVertex",s),this.segmentLabels?.set("stagedVertex",null!=s?this.coordinateHelper.pointToVector(s):null),null==s||"mouse"!==this._stagedPointerType?this.emit("cursor-remove"):this.emit("cursor-update",{updated:null,vertices:[{componentIndex:0,vertexIndex:this._activeComponent.vertices.length,coordinates:this.coordinateHelper.pointToArray(s)}],operation:"apply",type:"vertex-update"}))}_snapToClosingVertex(t){if(null==t||this._isDragging||"polygon"!==this.geometryType||this.numCommittedVertices<=2)return t;const e=this._mapToScreen(t);if(!e)return t;const i=this._activeComponent;return this._vertexWithinPointerDistance(i.vertices[0].pos,e)?this.firstVertex:this._vertexWithinPointerDistance(i.vertices.at(-1).pos,e)?this.lastVertex:t}_createManipulatorDragPipeline(t){switch(this.drawingMode){case"click":return this._createManipulatorDragPipelineClick(t);case"freehand":return this._createManipulatorDragPipelineFreehand(t);case"hybrid":return this._createManipulatorDragPipelineHybrid(t)}}_createManipulatorDragPipelineClick(t){return T(t,((t,e,i,n)=>{const o="touch"===n&&this._snappingEnabled;if(this.isCompleted||!o)return;const{snappingStep:r,cancelSnapping:s}=G({predicate:()=>o,snappingManager:this.snappingManager,snappingContext:new j({editGeometryOperations:this._editGeometryOperations,elevationInfo:this.elevationInfo,feature:this.graphic,pointer:n,visualizer:this.snappingVisualizer,drawConstraints:this.constraints}),updatingHandles:this._updatingHandles,useZ:!this._requiresScenePoint});i=i.next((t=>(o&&null!=this.snappingManager&&this.snappingManager.doneSnapping(),t))).next(s),e.next(this._screenToMapDragEventStep()).next((t=>("start"===t.action&&(this._processCursor(t.mapStart),("segment"===this.geometryType||o&&!this.numCommittedVertices)&&this.commitStagedVertex()),t))).next(S(this.view,this.elevationInfo)).next(...r).next((t=>(o&&(this._processCursor(t.mapEnd),"end"===t.action&&this.commitStagedVertex()),t))).next((t=>("end"===t.action&&("mouse"!==this._stagedPointerType&&this._snappingOperation.abort(),"segment"!==this.geometryType&&"point"!==this.geometryType||this.complete()),t)))}))}_createManipulatorDragPipelineFreehand(t){return T(t,((t,e)=>{this.isCompleted||e.next(this._screenToMapDragEventStep()).next((t=>("start"===t.action&&(this._snappingOperation.abort(),null==this.committableVertex&&this._processCursor(t.mapStart),"segment"===this.geometryType&&this.commitStagedVertex()),t))).next((t=>{switch(t.action){case"start":case"update":this._processCursor(t.mapEnd),"polygon"!==this.geometryType&&"polyline"!==this.geometryType||this.commitStagedVertex();break;case"end":this.complete()}return t}))}))}_createManipulatorDragPipelineHybrid(t){return T(t,((t,e)=>{this.isCompleted||e.next(this._screenToMapDragEventStep()).next((t=>("start"===t.action&&(this._snappingOperation.abort(),this.addHandles(this._editGeometryOperations.createUndoGroup(),z),this._processCursor(t.mapStart),this.commitStagedVertex()),t))).next((t=>{switch(t.action){case"start":case"update":this._processCursor(t.mapEnd),"polygon"!==this.geometryType&&"polyline"!==this.geometryType||this.commitStagedVertex();break;case"end":"mouse"!==this._stagedPointerType&&this._snappingOperation.abort(),this.removeHandles(z),"segment"!==this.geometryType&&"point"!==this.geometryType||this.complete()}return t}))}))}get _drawAtFixedElevation(){const{constraintsEnabled:t,constraintZ:e,geometryType:i,numCommittedVertices:n}=this;return t?null!=e||"segment"===i&&n>0:("segment"===i||"polygon"===i)&&n>0}_updateAndGetEffectiveDrawSurface(){const{constraintsEnabled:t,coordinateHelper:e,drawSurface:i,elevationDrawSurface:n,snapToSceneEnabled:o}=this;if(null==n)return i;if(!this.hasZ)return n.defaultZ=null,n;const r=this.elevationInfo?.mode;let s=this.defaultZ,a=t||"absolute-height"===r;if(null!=o&&(a=o),"on-the-ground"===r&&(a=!1),this._drawAtFixedElevation){s=(t?this.constraintZ:null)??e.getZ(this._activeComponent.vertices[0].pos),a=!1}return a?i:(n.defaultZ=s,n)}_mapToScreen(t){return this._updateAndGetEffectiveDrawSurface()?.mapToScreen(t)}_onHold(t){this._snappingOperation.abort(),"click"===this.drawingMode&&"touch"===t.pointerType&&this._snappingEnabled&&this._processCursor(t.mapPoint),t.stopPropagation()}_onImmediateClick(t){if(!("mouse"===t.pointerType&&2===t.button||this._manipulator.dragging))try{const{drawingMode:e,geometryType:i}=this;this._stagedPointerType=t.pointerType,this._stagedScreenPoint=t.screenPoint;const n=this._screenToMap(t.screenPoint);if(null==n)return;if(null==n||"freehand"===e&&"point"!==i&&"multipoint"!==i)return;if(this._snappingEnabled&&null!=this.cursorVertex||this._processCursor(n),null==this.committableVertex)return void this.complete();this.commitStagedVertex(),"mouse"!==t.pointerType&&this._processCursor(null),("freehand"===e&&"multipoint"!==this.geometryType||"point"===i||"segment"===i&&2===this.numCommittedVertices||"segment"===i&&"hybrid"===e&&1===this.numCommittedVertices)&&this.complete()}finally{t.stopPropagation()}}_onImmediateDoubleClick(t){this._manipulator.dragging||"point"===this.geometryType||(this.complete(),t.stopPropagation())}_onPointerMove(t){const e=d(t.x,t.y);this._stagedScreenPoint=e,this._stagedPointerType=t.pointerType,this._stagedPointerId=t.pointerId,this._isDragging?this._snappingOperation.abort():(t.stopPropagation(),this._processCursorMovementRelativeToSurface(e,t.pointerType))}_onKeyboardBasedChange(){"mouse"===this._stagedPointerType&&this._stagedScreenPoint&&null!=this._stagedPointerId&&!this._isDragging?this._processCursorMovementRelativeToSurface(this._stagedScreenPoint,this._stagedPointerType):this._snappingOperation.abort()}_processCursorMovementRelativeToSurface(t,e){const i=this._snappingOperation,n=this._screenToMap(t),o=this._requiresScenePoint?this.drawSurface?.screenToMap(t):null;if(null==n)return this._hideDefaultCursor=!0,this._processCursor(null),void i.abort();this._hideDefaultCursor=!1;const r=this.snappingManager;if(null==r)return this._processCursor(n),void i.abort();const s=this._getSnappingContext(e);this._updatingHandles.addPromise(a(i.snap({point:n,scenePoint:o},r,s)))}_applyConstraints(t){const{_constraint:e,constraints:i}=this;if(!t||!i||!e)return t;const{context:n}=i,o=E(t,n),r=o?e.closestTo(o):void 0;if(!r)return t;const s=I(r,t,n),a="2d"===this.view.type||"absolute-height"!==n.elevationInfo.mode;return null!=s&&a&&null!=this.constraintZ&&this.hasZ&&(s.z=this.constraintZ),s}_screenToMap(t){return t?this._updateAndGetEffectiveDrawSurface()?.screenToMap(t):null}_screenToMapDragEventStep(){let t=null;return e=>{if("start"===e.action&&(t=this._screenToMap(e.screenStart)),null==t)return null;const i=this._screenToMap(e.screenEnd);return null!=i?{...e,mapStart:t,mapEnd:i}:null}}_vertexWithinPointerDistance(t,e){const i=25,n=this._mapToScreen(this.coordinateHelper.vectorToDehydratedPoint(t));return null!=n&&R(n,e,i)}_getSnappingContext(t){const e=this._drawAtFixedElevation?this.elevationDrawSurface?.defaultZ:null;return new j({editGeometryOperations:this._editGeometryOperations,elevationInfo:this.elevationInfo,pointer:t,feature:this.graphic,visualizer:this.snappingVisualizer,selfSnappingZ:null!=e?{value:e,elevationInfo:this.elevationInfo}:null,drawConstraints:this.constraints})}};function R(t,e,i){const n=t.x-e.x,o=t.y-e.y;return n*n+o*o<=i}t([h()],F.prototype,"_hideDefaultCursor",void 0),t([h()],F.prototype,"_stagedPointerId",void 0),t([h()],F.prototype,"_isDragging",null),t([h()],F.prototype,"_snappingOperation",void 0),t([h()],F.prototype,"_snappingEnabled",null),t([h({constructOnly:!0})],F.prototype,"graphic",void 0),t([h()],F.prototype,"constraintsEnabled",void 0),t([h()],F.prototype,"constraints",void 0),t([h()],F.prototype,"_constraint",null),t([h()],F.prototype,"constraintZ",void 0),t([h()],F.prototype,"defaultZ",void 0),t([h()],F.prototype,"isDraped",void 0),t([h({constructOnly:!0})],F.prototype,"automaticLengthMeasurementUtils",void 0),t([h({value:x})],F.prototype,"drawingMode",null),t([h({constructOnly:!0})],F.prototype,"elevationDrawSurface",void 0),t([h({constructOnly:!0})],F.prototype,"elevationInfo",void 0),t([h({constructOnly:!0,type:H})],F.prototype,"labelOptions",void 0),t([h({constructOnly:!0})],F.prototype,"geometryType",void 0),t([h({constructOnly:!0})],F.prototype,"hasM",void 0),t([h({constructOnly:!0})],F.prototype,"hasZ",void 0),t([h()],F.prototype,"cursor",void 0),t([h()],F.prototype,"effectiveCursor",null),t([h()],F.prototype,"loading",void 0),t([h({constructOnly:!0})],F.prototype,"manipulators",void 0),t([h({constructOnly:!0})],F.prototype,"drawSurface",void 0),t([h({constructOnly:!0})],F.prototype,"segmentLabels",void 0),t([h({constructOnly:!0})],F.prototype,"snappingManager",void 0),t([h({constructOnly:!0})],F.prototype,"snappingVisualizer",void 0),t([h()],F.prototype,"snapToSceneEnabled",void 0),t([h({readOnly:!0})],F.prototype,"cursorVertex",null),t([h({readOnly:!0})],F.prototype,"visualizationCursorVertex",null),t([h()],F.prototype,"committableVertex",null),t([h()],F.prototype,"firstVertex",void 0),t([h()],F.prototype,"lastVertex",void 0),t([h()],F.prototype,"secondToLastVertex",void 0),t([h()],F.prototype,"updating",null),t([h({constructOnly:!0})],F.prototype,"view",void 0),F=t([u("esri.views.draw.DrawOperation")],F);export{F as DrawOperation,L as defaultCursor,U as defaultLoadingCursor};