zoukankan      html  css  js  c++  java
  • engine的工具中实现Snapping(捕捉)

    http://blog.csdn.net/rrrrssss00/article/details/5809184 在Engine的工具(ITool)里:   OnClick事件处理函数中: 首先需要获取一个图层,作为Snapping的参照, IFeatureLayer targetLayer   然后声明一个IMovePointFeedBack作为鼠标移动时捕捉点的显示: [c-sharp]view plaincopyprint?
    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;
    IMovePointFeedback m_pMovePtFeed = new MovePointFeedback(); mFeedback = (IDisplayFeedback)m_pMovePtFeed; ISimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbolClass(); IRgbColor pRGBColor = new RgbColorClass(); pRGBColor.Red = 0; pRGBColor.Green = 0; pRGBColor.Blue = 0; simpleMarkerSymbol.Color = pRGBColor; simpleMarkerSymbol.Size = 3; simpleMarkerSymbol.Style = ESRI.ArcGIS.Display.esriSimpleMarkerStyle.esriSMSSquare; ISymbol symbol = simpleMarkerSymbol as ISymbol; symbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen; //symbol.ROP2 = esriRasterOpCode.; m_pMovePtFeed.Symbol = (ISymbol)simpleMarkerSymbol;   然后开始Feedback的显示(tmpPoint是指开始的点,其实影响不大,如果不想要源点在屏幕上的话,可以取一个在屏幕外的点): [c-sharp]view plaincopyprint?
    1. m_pMovePtFeed.Display = mMapControl.ActiveView.ScreenDisplay;
    2. m_pMovePtFeed.Start(tmpPoint, tmpPoint);
    m_pMovePtFeed.Display = mMapControl.ActiveView.ScreenDisplay;m_pMovePtFeed.Start(tmpPoint, tmpPoint);   在OnMouseMove事件中: [c-sharp]view plaincopyprint?
    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);
    IPoint pPoint2 = null; IPoint pPoint = pMap.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y); pPoint2 = Snapping(pPoint.X, pPoint.Y, targetLayer, pMap, 10); if (pPoint2 == null) pPoint2 = pPoint; ((IMovePointFeedback)mFeedback).MoveTo(pPoint2);   其中Snapping函数即为最主要的查找函数,其功能为根据输入的点坐标在目标图层上查找最为相近的点(也即需要捕捉的点),返回该点,若没有找到则返回NULL,最后一个参数的含义是,在地图控件上,以多少个像素为单位在周边查找捕捉点. [c-sharp]view plaincopyprint?
    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 == null) return 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.         }
    publicIPoint Snapping(double x, double y, IFeatureLayer iFeatureLyr,IMapControl3 axMapControl1,double snappingDis) { IPoint iHitPoint =null; IMap iMap = axMapControl1.Map; IActiveView iView =axMapControl1.ActiveView; IFeatureClass iFClss =iFeatureLyr.FeatureClass; IPoint point = new PointClass();point.PutCoords(x, y); double length =ConvertPixelsToMapUnits(axMapControl1.ActiveView, snappingDis);ITopologicalOperator pTopo = point as ITopologicalOperator; IGeometrypGeometry = pTopo.Buffer(length).Envelope as IGeometry; ISpatialFilterspatialFilter = new SpatialFilterClass(); spatialFilter.GeometryField =iFeatureLyr.FeatureClass.ShapeFieldName; spatialFilter.SpatialRel =esriSpatialRelEnum.esriSpatialRelIntersects; spatialFilter.Geometry =pGeometry; IFeatureCursor cursor = iFClss.Search(spatialFilter, false);IFeature iF = cursor.NextFeature(); if (iF == null) return null; IPointiHitPt = new ESRI.ArcGIS.Geometry.Point(); IHitTest iHitTest = iF.Shapeas IHitTest; double hitDist = 0; int partIndex = 0; int vertexIndex =0; bool bVertexHit = false; // Tolerance in pixels for line hits doubletol = ConvertPixelsToMapUnits(iView, snappingDis); if(iHitTest.HitTest(point, tol,esriGeometryHitPartType.esriGeometryPartBoundary, iHitPt, ref hitDist,ref partIndex, ref vertexIndex, ref bVertexHit)) { iHitPoint = iHitPt;} //axMapControl1.ActiveView.Refresh(); return iHitPoint; } publicdouble ConvertPixelsToMapUnits(IActiveView pActiveView, doublepixelUnits) { double realWorldDisplayExtent; int pixelExtent; doublesizeOfOnePixel; pixelExtent =pActiveView.ScreenDisplay.DisplayTransformation.get_DeviceFrame().right-pActiveView.ScreenDisplay.DisplayTransformation.get_DeviceFrame().left;realWorldDisplayExtent =pActiveView.ScreenDisplay.DisplayTransformation.VisibleBounds.Width;sizeOfOnePixel = realWorldDisplayExtent / pixelExtent; returnpixelUnits * sizeOfOnePixel; }   此时即可实现鼠标实时地捕捉目标图层上的对象,若需要获取当前位置的捕捉点时,则可以在相应事件(例如OnMouseDown或OnDbClick)中调用: [c-sharp]view plaincopyprint?
    1. IPoint pPoint = ((IMovePointFeedback)mFeedback).Stop();
    IPoint pPoint = ((IMovePointFeedback)mFeedback).Stop(); 这时实时捕捉将会停止,若需要重新开始捕捉,则在之后调用这些语句即可: [c-sharp]view plaincopyprint?
    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);
  • 相关阅读:
    java基础知识回顾之final
    基础知识《十四》Java异常的栈轨迹fillInStackTrace和printStackTrace的用法
    基础知识《六》---Java集合类: Set、List、Map、Queue使用场景梳理
    基础知识《五》---Java多线程的常见陷阱
    基础知识《四》---Java多线程学习总结
    《转》如何选择合适的服务器托管商
    基础知识《三》java修饰符
    基础知识《零》---Java程序运行机制及运行过程
    应用 JD-Eclipse 插件实现 RFT 中 .class 文件的反向编译
    DOS命令符基本操作
  • 原文地址:https://www.cnblogs.com/adodo1/p/4328014.html
Copyright © 2011-2022 走看看