ArcGIS Engine 捕捉

原文 ArcGIS Engine 捕捉

bool bCreateElement = true;
int internalTime = 5;//时间间隔
int snapTime = 10;//初始值
IElement m_element = null;  //界面绘制点元素
IPoint currentPoint = new PointClass();  //当前鼠标点
IPoint snapPoint = null;  //捕捉到的点
IMovePointFeedback pFeedback = new MovePointFeedbackClass();

public void DoMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
{
    AxMapControl axMapControl1 = sender as AxMapControl;
    currentPoint.PutCoords(e.mapX, e.mapY);
    if (action == ActionType.CreateFeature)
    {
    snapTime++;
    snapTime = snapTime%internalTime ;
    ILayer layer = GetLayerByName(snapLayer, axMapControl1);
    IFeatureLayer m_iFeatureLyr = layer as IFeatureLayer;
    if (bCreateElement)
    {
    CreateMarkerElement(currentPoint,axMapControl1);
    bCreateElement = false;
    }       
    if (snapPoint == null)
    ElementMoveTo(currentPoint, axMapControl1);
    //鼠标自动扑获顶点  
    if (snapTime == 0)
    snapPoint = Snapping(e.mapX, e.mapY, m_iFeatureLyr,     axMapControl1);
    if (snapPoint != null && snapTime == 0)
    ElementMoveTo(snapPoint, axMapControl1);
    }
}

/// <summary>
/// 捕捉
/// </summary>
/// <param name=”x”></param>
/// <param name=”y”></param>
/// <param name=”iFeatureLyr”></param>
/// <param name=”axMapControl1″></param>
/// <returns></returns>
public IPoint Snapping(double x, double y, IFeatureLayer iFeatureLyr, AxMapControl axMapControl1)
{
    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, 8);
    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.esriSpatialRelCrosses;
    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, 8);

    if (iHitTest.HitTest(point, tol, esriGeometryHitPartType.esriGeometryPartBoundary, iHitPt, ref hitDist, ref partIndex, ref vertexIndex, ref bVertexHit))
    {
    iHitPoint = iHitPt;
    }
    axMapControl1.ActiveView.Refresh();
    return iHitPoint;
}

/// <summary>
/// 创建新的element用于显示
/// </summary>
/// <param name=”point”></param>
/// <param name=”axMapControl1″></param>
public void CreateMarkerElement(IPoint point, AxMapControl axMapControl1)
{
    IActiveView iView = axMapControl1.ActiveView;
    IGraphicsContainer iGraphContainer = axMapControl1.Map as IGraphicsContainer;
    //建立一个marker元素
    IMarkerElement iMarkerElement = new MarkerElement() as IMarkerElement;
    ISimpleMarkerSymbol iSym = new SimpleMarkerSymbol();
    //符号化元素
    IRgbColor iColor = new RgbColor();
    iColor.Red = 0;
    iColor.Blue = 100;
    iColor.Green = 255;
    iSym.Color = iColor;
    IRgbColor iColor2 = new RgbColor();
    iColor2.Red = 0;
    iColor2.Blue = 0;
    iColor2.Green = 0;
    iSym.Outline = true;
    iSym.OutlineColor = iColor2 as IColor;
    iSym.OutlineSize = 1;
    iSym.Size = 5;
    iSym.Style. = esriSimpleMarkerStyle.esriSMSCircle;
    ISymbol symbol = iSym as ISymbol;
    symbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;
    iMarkerElement.Symbol = iSym;
    m_element = iMarkerElement as IElement;
    m_element.Geometry = point as IGeometry;
    iGraphContainer.AddElement(m_element, 0);
    iView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, m_element, null);
    IGeometry iGeo = m_element.Geometry;
    pFeedback.Display = iView.ScreenDisplay;
    pFeedback.Symbol = iSym as ISymbol;
    pFeedback.Start(iGeo as IPoint, point);
}
/// <summary>
/// 移动元素
/// </summary>
/// <param name=”iPt”></param>
/// <param name=”axMapControl1″></param>
public void ElementMoveTo(IPoint iPt, AxMapControl axMapControl1)
{
    //移动元素
    pFeedback.MoveTo(iPt);
    IGeometry iGeo1 = null;
    IGeometry iGeoResult;
    if (m_element != null)
    {
  iGeo1 = m_element.Geometry;
  iGeoResult = pFeedback.Stop();
  //map.ActiveView.Refresh();
  m_element.Geometry = iGeoResult;
  //更新该元素的位置
  axMapControl1.ActiveView.GraphicsContainer.UpdateElement(m_element);
  //重新移动元素
  pFeedback.Start(iGeo1 as IPoint, iPt);
  //map.ActiveView.Refresh();
  axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
    }
}

public ILayer GetLayerByName(string layerName, AxMapControl axMapControl1)
{
    for (int i = 0; i < axMapControl1.LayerCount; i++)
    {
   if (axMapControl1.get_Layer(i).Name.Equals(layerName))
      return axMapControl1.get_Layer(i);
    }
    return null;
}

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;
}
原文地址:https://www.cnblogs.com/arxive/p/6017167.html