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

     

    在Engine的工具(ITool)里:

    OnClick事件处理函数中:

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

    IFeatureLayer targetLayer

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

    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是指开始的点,其实影响不大,如果不想要源点在屏幕上的话,可以取一个在屏幕外的点):

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

    在OnMouseMove事件中:

    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,最后一个参数的含义是,在地图控件上,以多少个像素为单位在周边查找捕捉点.

    public IPoint 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;  
        IGeometry pGeometry = pTopo.Buffer(length).Envelope as IGeometry;  
        ISpatialFilter spatialFilter = 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;  
        IPoint iHitPt = new ESRI.ArcGIS.Geometry.Point();  
        IHitTest iHitTest = iF.Shape as IHitTest;  
        double hitDist = 0;  
        int partIndex = 0;  
        int vertexIndex = 0;  
        bool bVertexHit = false;  
        // Tolerance in pixels for line hits  
        double tol = 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;  
    }  
    public double ConvertPixelsToMapUnits(IActiveView pActiveView, double pixelUnits)  
    {  
        double realWorldDisplayExtent;  
        int pixelExtent;  
        double sizeOfOnePixel;  
        pixelExtent = pActiveView.ScreenDisplay.DisplayTransformation.get_DeviceFrame().right - pActiveView.ScreenDisplay.DisplayTransformation.get_DeviceFrame().left;  
        realWorldDisplayExtent = pActiveView.ScreenDisplay.DisplayTransformation.VisibleBounds.Width;  
        sizeOfOnePixel = realWorldDisplayExtent / pixelExtent;  
        return pixelUnits * sizeOfOnePixel;  
    }

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

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

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

    //重新开始Snap  
    IPoint tmpPoint = new PointClass();  
    tmpPoint.PutCoords(pMap.Extent.XMin - 1, pMap.Extent.YMin - 1);  
    IMovePointFeedback m_pMovePtFeed = (IMovePointFeedback)mFeedback;  
    m_pMovePtFeed.Display = pMap.ActiveView.ScreenDisplay;  
    m_pMovePtFeed.Start(tmpPoint, tmpPoint);  
  • 相关阅读:
    写页面得来的体会
    C#&java重学笔记(面向对象)
    C#&java重学笔记(函数)
    C#&java重学笔记(变量与操作符)
    深入JS第一天:原型和它的小伙伴们(一)
    兼容性积累
    再深入一点ajax
    Android之内存泄漏调试学习与总结
    优雅地实现Android主流图片加载框架封装,可无侵入切换框架
    优雅地实现Android主流图片加载框架封装,可无侵入切换框架
  • 原文地址:https://www.cnblogs.com/arxive/p/6262694.html
Copyright © 2011-2022 走看看