forked from Esri/arcgis-js-api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSnappingManager.js
25 lines (24 loc) · 10 KB
/
SnappingManager.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// COPYRIGHT © 2021 Esri
//
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
//
// This material is licensed for use under the Esri Master License
// Agreement (MLA), and is bound by the terms of that agreement.
// You may redistribute and use this code without modification,
// provided you adhere to the terms of the MLA and include this
// copyright notice.
//
// See use restrictions at http://www.esri.com/legal/pdfs/mla_e204_e300/english
//
// For additional information, contact:
// Environmental Systems Research Institute, Inc.
// Attn: Contracts and Legal Services Department
// 380 New York Street
// Redlands, California, USA 92373
// USA
//
// email: [email protected]
//
// See http://js.arcgis.com/3.36/esri/copyright.txt for details.
define(["dojo/_base/declare","dojo/_base/connect","dojo/_base/lang","dojo/_base/array","dojo/_base/Color","dojo/_base/Deferred","dojo/has","dojo/keys","./kernel","./graphic","./geometry/ScreenPoint","./geometry/Extent","./symbols/SimpleMarkerSymbol","./symbols/SimpleLineSymbol","./tasks/query"],(function(e,n,t,a,i,s,o,r,p,c,h,l,y,_,g){var f=e(null,{declaredClass:"esri.SnappingManager",constructor:function(e){if((e=e||{}).map||console.error("map is not specified for SnappingManager"),this.map=e.map,this.tolerance=e.tolerance||15,this.layerInfos=[],e.layerInfos)this.layerInfos=e.layerInfos;else{var a;for(a=0;a<this.map.graphicsLayerIds.length;a++){var s=this.map.getLayer(this.map.graphicsLayerIds[a]);this.layerInfos.push({layer:s})}if(this.map.loaded)this.layerInfos.push({layer:this.map.graphics});else var p=n.connect(this.map,"onLoad",this,(function(e){n.disconnect(p),p=null,this.layerInfos.push({layer:this.map.graphics}),this.setLayerInfos(this.layerInfos)}))}e.snapPointSymbol?this.snapPointSymbol=e.snapPointSymbol:this.snapPointSymbol=new y(y.STYLE_CROSS,15,new _(_.STYLE_SOLID,new i([0,255,255]),1),new i([0,255,0,0])),e.alwaysSnap?this.alwaysSnap=e.alwaysSnap:this.alwaysSnap=!1,e.snapKey?this.snapKey=e.snapKey:this.snapKey=o("mac")?r.META:r.CTRL,this._SelectionLyrQuery=new g,this._SelectionLyrQuery.spatialRelationship=g.SPATIAL_REL_INTERSECTS,this._snappingGraphic=new c,this.setLayerInfos(this.layerInfos),this._currentGraphicOption={snapToPoint:!0,snapToVertex:!0,snapToLastVertex:!0,snapToEdge:!0},this._snappingCallback=t.hitch(this,this._snappingCallback)},getSnappingPoint:function(e){var n=this.layers,i=this.tolerance,o=this.map,r=this.layerOptions,p=o.toMap(e.offset(-i,i)),c=o.toMap(e.offset(i,-i)),h=new l(p.x,p.y,c.x,c.y,o.spatialReference),y=new g;y.geometry=h,y.spatialRelationship=g.SPATIAL_REL_INTERSECTS;var _,f,u=[],S=[],d=this._extractPointsAndLines,m=new s,x=0,L=h.xmin,v=h.xmax;a.forEach(n,(function(e,n){e.visible&&e.loaded&&"esri.layers.FeatureLayer"===e.declaredClass&&e.mode!==e.constructor.MODE_SELECTION&&x++})),o.spatialReference._isWrappable()&&(L=l.prototype._normalizeX(h.xmin,o.spatialReference._getInfo()).x,v=l.prototype._normalizeX(h.xmax,o.spatialReference._getInfo()).x);var E=new l(L,h.ymin,v,h.ymax,o.spatialReference);a.forEach(n,(function(e,n){if("esri.layers.GraphicsLayer"===e.declaredClass&&e.visible){var t=[];a.forEach(e.graphics,(function(e){e&&e.visible&&E.intersects(e.geometry)&&t.push(e)}));var i=d(t,r[n]);u=u.concat(i[0]),S=S.concat(i[1])}}));var P=t.hitch(this,(function(n){if(x--,n instanceof Error){console.log("getSnappingPoint: query features failed")}else{var t=d(n.features,r[f]);u=u.concat(t[0]),S=S.concat(t[1])}x||(_=this._getSnappingPoint(u,S,e),m.callback(_))})),T=!1;return a.forEach(n,(function(e,n){e.visible&&e.loaded&&(f=n,"esri.layers.FeatureLayer"===e.declaredClass&&e.mode!==e.constructor.MODE_SELECTION&&(T=!0,e.queryFeatures(y,P,P)))})),T||(_=this._getSnappingPoint(u,S,e),m.callback(_)),m},setLayerInfos:function(e){var n;for(this.layers=[],this.layerOptions=[],n=0;n<e.length;n++)this.layers.push(e[n].layer),this.layerOptions.push({snapToPoint:!0,snapToVertex:!0,snapToEdge:!0}),!1===e[n].snapToPoint&&(this.layerOptions[n].snapToPoint=e[n].snapToPoint),!1===e[n].snapToVertex&&(this.layerOptions[n].snapToVertex=e[n].snapToVertex),!1===e[n].snapToEdge&&(this.layerOptions[n].snapToEdge=e[n].snapToEdge);this._featurePtsFromSelectionLayer=[],this._featureLinesFromSelectionLayer=[],this._selectionLayers=[],this._selectionLayerOptions=[],a.forEach(this.layers,(function(e,n){"esri.layers.FeatureLayer"===e.declaredClass&&e.mode===e.constructor.MODE_SELECTION&&(this._selectionLayers.push(e),this._selectionLayerOptions.push(this.layerOptions[n]))}),this),this.layerInfos=e},destroy:function(){n.disconnect(this._onExtentChangeConnect),this._killOffSnapping(),this._featurePtsFromSelectionLayer=this._featureLinesFromSelectionLayer=this._currentFeaturePts=this._currentFeatureLines=this.layers=this.map=null},_startSelectionLayerQuery:function(){n.disconnect(this._onExtentChangeConnect),this._mapExtentChangeHandler(this._selectionLayers,this._selectionLayerOptions,this.map.extent),this._onExtentChangeConnect=n.connect(this.map,"onExtentChange",t.hitch(this,"_mapExtentChangeHandler",this._selectionLayers,this._selectionLayerOptions))},_stopSelectionLayerQuery:function(){n.disconnect(this._onExtentChangeConnect)},_mapExtentChangeHandler:function(e,n,i){var s;this._featurePtsFromSelectionLayer=[],this._featureLinesFromSelectionLayer=[],this._SelectionLyrQuery.geometry=i;var o=t.hitch(this,(function(e){if(e instanceof Error){console.log("getSnappingPoint: query features failed")}else{var t=this._extractPointsAndLines(e.features,n[s]);this._featurePtsFromSelectionLayer=this._featurePtsFromSelectionLayer.concat(t[0]),this._featureLinesFromSelectionLayer=this._featureLinesFromSelectionLayer.concat(t[1])}}));a.forEach(e,(function(e,n){e.visible&&e.loaded&&(s=n,e.queryFeatures(this._SelectionLyrQuery,o,o))}),this)},_extractPointsAndLines:function(e,n){var t,i,s=!n||!1!==n.snapToLastVertex,o=[],r=[];return a.forEach(e,(function(e,a){if((!e._graphicsLayer||e.visible)&&e.geometry&&e._isSnapTarget)if("point"===e.geometry.type&&n.snapToPoint)o.push(e.geometry);else if("polyline"===e.geometry.type)for(t=0;t<e.geometry.paths.length;t++){r.push("lineStart");var p=e.geometry.paths[t].length;for(i=0;i<p;i++)if(s||i!==p-1){var c=e.geometry.getPoint(t,i);n.snapToVertex&&o.push(c),n.snapToEdge&&r.push(c)}r.push("lineEnd")}else if("polygon"===e.geometry.type)for(t=0;t<e.geometry.rings.length;t++){r.push("lineStart");var h=e.geometry.rings[t].length;for(i=0;i<h;i++)if(s||i!==h-1){var l=e.geometry.getPoint(t,i);n.snapToVertex&&o.push(l),n.snapToEdge&&r.push(l)}r.push("lineEnd")}})),[o,r]},_getSnappingPoint:function(e,n,t){var i,s,o,r,p=this.tolerance,c=this.map,l=this.map._getFrameWidth();if(e=e.concat(this._featurePtsFromSelectionLayer),n=n.concat(this._featureLinesFromSelectionLayer),this._currentGraphic){var y=this._extractPointsAndLines([this._currentGraphic],this._currentGraphicOption);e=e.concat(y[0]),n=n.concat(y[1])}if(a.forEach(e,(function(e,n){var a=c.toScreen(e,!0);if(-1!==l&&(a.x=a.x%l,a.x<0&&(a.x+=l),c.width>l))for(var s=(c.width-l)/2;a.x<s;)a.x+=l;(i=Math.sqrt((a.x-t.x)*(a.x-t.x)+(a.y-t.y)*(a.y-t.y)))<=p&&(p=i,o=a.x,r=a.y)})),o){var _=new h(o,r);s=_=c.toMap(_)}else{var g,f,u,S;for(p=this.tolerance,u=0;u<n.length;u++)if("lineStart"===n[u])for(S=u+1;S<n.length;S++){if("lineEnd"!==n[S+1]&&"lineStart"!==n[S+1]&&"lineEnd"!==n[S]&&"lineStart"!==n[S]){var d=c.toScreen(n[S],!0),m=c.toScreen(n[S+1],!0),x=d.x>=m.x?d:m,L=d.x>=m.x?m:d;-1!==l&&(x.x=x.x%l,x.x<0&&(x.x+=l),L.x=L.x%l,L.x<0&&(L.x+=l),L.x>x.x&&(L.x-=l));var v,E,P,T,M,C,b=x.x,w=x.y,I=L.x,O=L.y;if(b===I)v=b,E=t.y,P=T=b,M=w<=O?w:O,C=w<=O?O:w;else if(w===O)v=t.x,E=w,P=b<=I?b:I,T=b<=I?I:b,M=C=w;else{var F=(O-w)/(I-b),G=(w*I-b*O)/(I-b),K=(b-I)/(O-w);E=F*(v=(G-(t.y*O-t.y*w-t.x*b+t.x*I)/(O-w))/(K-F))+G,P=b<=I?b:I,T=b<=I?I:b,M=w<=O?w:O,C=w<=O?O:w}if(v>=P&&v<=T&&E>=M&&E<=C){var D=Math.sqrt((t.x-v)*(t.x-v)+(t.y-E)*(t.y-E));D<=p&&(p=D,g=v,f=E)}else{var k,R=Math.sqrt((b-t.x)*(b-t.x)+(w-t.y)*(w-t.y)),A=Math.sqrt((I-t.x)*(I-t.x)+(O-t.y)*(O-t.y));R<=A?(k=R,v=b,E=w):(k=A,v=I,E=O),k<=p&&(p=k,g=v,f=E)}}if("lineEnd"===n[S]){u=S;break}}if(g){var H=new h(g,f);s=H=c.toMap(H)}}return s},_setGraphic:function(e,n){this._currentGraphic=e,this._currentGraphicOption.snapToLastVertex=!n||!1!==n.snapToLastVertex},_addSnappingPointGraphic:function(){var e=this.map,n=this.snapPointSymbol;this._snappingGraphic.setSymbol(n),e.graphics.add(this._snappingGraphic)},_setUpSnapping:function(){var e=this.map;this._onSnapKeyDown_connect=n.connect(e,"onKeyDown",this,"_onSnapKeyDownHandler"),this._onSnapKeyUp_connect=n.connect(e,"onKeyUp",this,"_onSnapKeyUpHandler"),this._onSnappingMouseMove_connect=n.connect(e,"onMouseMove",this,"_onSnappingMouseMoveHandler"),this._onSnappingMouseDrag_connect=n.connect(e,"onMouseDrag",this,"_onSnappingMouseMoveHandler"),this.alwaysSnap&&this._activateSnapping()},_killOffSnapping:function(){n.disconnect(this._onSnapKeyDown_connect),n.disconnect(this._onSnapKeyUp_connect),n.disconnect(this._onSnappingMouseMove_connect),n.disconnect(this._onSnappingMouseDrag_connect),this._deactivateSnapping()},_onSnapKeyDownHandler:function(e){e.keyCode===this.snapKey&&(n.disconnect(this._onSnapKeyDown_connect),this.alwaysSnap?this._deactivateSnapping():this._activateSnapping())},_activateSnapping:function(){this._snappingActive=!0,this._addSnappingPointGraphic(),this._currentLocation&&this._onSnappingMouseMoveHandler(this._currentLocation)},_onSnapKeyUpHandler:function(e){e.keyCode===this.snapKey&&(this._onSnapKeyDown_connect=n.connect(this.map,"onKeyDown",this,"_onSnapKeyDownHandler"),this.alwaysSnap?this._activateSnapping():this._deactivateSnapping())},_deactivateSnapping:function(){this._snappingActive=!1,this._snappingPoint=null,this.map.graphics.remove(this._snappingGraphic),this._snappingGraphic.setGeometry(null)},_onSnappingMouseMoveHandler:function(e){(this._currentLocation=e,this._snappingPoint=null,this._snappingActive)&&(this._snappingGraphic.hide(),this.getSnappingPoint(e.screenPoint).addCallback(this._snappingCallback))},_snappingCallback:function(e){this._snappingPoint=e,e&&(this._snappingGraphic.show(),this._snappingGraphic.setGeometry(e))}});return o("extend-esri")&&(p.SnappingManager=f),f}));