Arcengine的工具中实现Snapping(捕捉)

在Engine的工具(ITool)里:

 

OnClick事件处理函数中:

首先需要获取一个图层,作为Snapping的参照,

IFeatureLayer targetLayer

 

然后声明一个IMovePointFeedBack作为鼠标移动时捕捉点的显示:

[c-sharp] view
plain
 copy

  1. IMovePointFeedback m_pMovePtFeed = new MovePointFeedback();  
  2. mFeedback = (IDisplayFeedback)m_pMovePtFeed;  
  3. ISimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbolClass();  
  4. IRgbColor pRGBColor = new RgbColorClass();  
  5. pRGBColor.Red = 0;  
  6. pRGBColor.Green = 0;  
  7. pRGBColor.Blue = 0;  
  8. simpleMarkerSymbol.Color = pRGBColor;  
  9. simpleMarkerSymbol.Size = 3;  
  10. simpleMarkerSymbol.Style = ESRI.ArcGIS.Display.esriSimpleMarkerStyle.esriSMSSquare;  
  11. ISymbol symbol = simpleMarkerSymbol as ISymbol;  
  12. symbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;  
  13. //symbol.ROP2 = esriRasterOpCode.;  
  14. m_pMovePtFeed.Symbol = (ISymbol)simpleMarkerSymbol;  

 

然后开始Feedback的显示(tmpPoint是指开始的点,其实影响不大,如果不想要源点在屏幕上的话,可以取一个在屏幕外的点):

[c-sharp] view
plain
 copy

  1. m_pMovePtFeed.Display = mMapControl.ActiveView.ScreenDisplay;  
  2. m_pMovePtFeed.Start(tmpPoint, tmpPoint);  

 

在OnMouseMove事件中:

[c-sharp] view
plain
 copy

  1. IPoint pPoint2 = null;  
  2. IPoint pPoint = pMap.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);  
  3. pPoint2 = Snapping(pPoint.X, pPoint.Y, targetLayer, pMap, 10);  
  4. if (pPoint2 == null)  
  5. pPoint2 = pPoint;  
  6. ((IMovePointFeedback)mFeedback).MoveTo(pPoint2);  

 

其中Snapping函数即为最主要的查找函数,其功能为根据输入的点坐标在目标图层上查找最为相近的点(也即需要捕捉的点),返回该点,若没有找到则返回NULL,最后一个参数的含义是,在地图控件上,以多少个像素为单位在周边查找捕捉点.

[c-sharp] view
plain
 copy

  1. public IPoint Snapping(double x, double y, IFeatureLayer iFeatureLyr, IMapControl3 axMapControl1,double snappingDis)  
  2.         {  
  3.             IPoint iHitPoint = null;  
  4.             IMap iMap = axMapControl1.Map;  
  5.             IActiveView iView = axMapControl1.ActiveView;  
  6.             IFeatureClass iFClss = iFeatureLyr.FeatureClass;  
  7.             IPoint point = new PointClass();  
  8.             point.PutCoords(x, y);  
  9.             double length = ConvertPixelsToMapUnits(axMapControl1.ActiveView, snappingDis);  
  10.             ITopologicalOperator pTopo = point as ITopologicalOperator;  
  11.             IGeometry pGeometry = pTopo.Buffer(length).Envelope as IGeometry;  
  12.             ISpatialFilter spatialFilter = new SpatialFilterClass();  
  13.             spatialFilter.GeometryField = iFeatureLyr.FeatureClass.ShapeFieldName;  
  14.             spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;  
  15.             spatialFilter.Geometry = pGeometry;  
  16.             IFeatureCursor cursor = iFClss.Search(spatialFilter, false);  
  17.             IFeature iF = cursor.NextFeature();  
  18.             if (iF == nullreturn null;  
  19.             IPoint iHitPt = new ESRI.ArcGIS.Geometry.Point();  
  20.             IHitTest iHitTest = iF.Shape as IHitTest;  
  21.             double hitDist = 0;  
  22.             int partIndex = 0;  
  23.             int vertexIndex = 0;  
  24.             bool bVertexHit = false;  
  25.             // Tolerance in pixels for line hits  
  26.             double tol = ConvertPixelsToMapUnits(iView, snappingDis);  
  27.             if (iHitTest.HitTest(point, tol, esriGeometryHitPartType.esriGeometryPartBoundary,  
  28.                 iHitPt, ref hitDist, ref partIndex, ref vertexIndex, ref bVertexHit))  
  29.             {  
  30.                 iHitPoint = iHitPt;  
  31.             }  
  32.             //axMapControl1.ActiveView.Refresh();  
  33.             return iHitPoint;  
  34.         }  
  35.         public double ConvertPixelsToMapUnits(IActiveView pActiveView, double pixelUnits)  
  36.         {  
  37.             double realWorldDisplayExtent;  
  38.             int pixelExtent;  
  39.             double sizeOfOnePixel;  
  40.             pixelExtent = pActiveView.ScreenDisplay.DisplayTransformation.get_DeviceFrame().right – pActiveView.ScreenDisplay.DisplayTransformation.get_DeviceFrame().left;  
  41.             realWorldDisplayExtent = pActiveView.ScreenDisplay.DisplayTransformation.VisibleBounds.Width;  
  42.             sizeOfOnePixel = realWorldDisplayExtent / pixelExtent;  
  43.             return pixelUnits * sizeOfOnePixel;  
  44.         }  

 

此时即可实现鼠标实时地捕捉目标图层上的对象,若需要获取当前位置的捕捉点时,则可以在相应事件(例如OnMouseDown或OnDbClick)中调用:

[c-sharp] view
plain
 copy

  1. IPoint pPoint = ((IMovePointFeedback)mFeedback).Stop();  

这时实时捕捉将会停止,若需要重新开始捕捉,则在之后调用这些语句即可:

[c-sharp] view
plain
 copy

  1. //重新开始Snap  
  2. IPoint tmpPoint = new PointClass();  
  3. tmpPoint.PutCoords(pMap.Extent.XMin – 1, pMap.Extent.YMin – 1);  
  4. IMovePointFeedback m_pMovePtFeed = (IMovePointFeedback)mFeedback;  
  5. m_pMovePtFeed.Display = pMap.ActiveView.ScreenDisplay;  
  6. m_pMovePtFeed.Start(tmpPoint, tmpPoint);  

转自:点击打开链接

转载自:https://blog.csdn.net/kone0611/article/details/73135729

You may also like...