捕捉功能的实现完整版
bool bCreateElement = true;
//时间间隔
int internalTime = 5;
//初始值
int snapTime = 10;
//界面绘制点元素
IElement m_element = null;
//当前鼠标点
IPoint currentPoint = new PointClass();
//捕捉到得点
IPoint snapPoint = null;
//移动点反馈对象
IMovePointFeedback movePointFeedback = new MovePointFeedbackClass();
//捕捉图层
string snapLayer = "";
public Form1()
{
InitializeComponent();
}
//鼠标移动事件
private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
{
currentPoint.PutCoords(e.mapX, e.mapY);
snapTime++;
snapTime = snapTime % internalTime;
//通过名称获取图层
ILayer pLayer = GetLayerByName(snapLayer, axMapControl1);
IFeatureLayer featureLayer = pLayer as IFeatureLayer;
if (bCreateElement)
{
CreateMarkerElement(currentPoint);
bCreateElement = false;
}
if (snapPoint == null)
{
ElementMoveTo(currentPoint);
}
//鼠标光标自动捕获顶点
if (snapTime == 0)
{
snapPoint = Snapping(e.mapX, e.mapY, featureLayer);
}
if (snapPoint != null & snapTime == 0)
{
ElementMoveTo(snapPoint);
}
}
//捕捉
public IPoint Snapping(double x, double y, IFeatureLayer featureLayer)
{
IMap pMap = axMapControl1.Map;
IActiveView activeView = axMapControl1.ActiveView;
IFeatureClass featureClass = featureLayer.FeatureClass;
IPoint point = new PointClass();
point.PutCoords(x, y);
IPoint hitPoint1 = new PointClass();
IPoint hitPoint2 = new PointClass();
// IGeometryCollection pGeometryCol = null;
IGeometryCollection pGeometryCol = new GeometryBagClass();
IFeature feature;
int flag = 0;
switch (featureClass.ShapeType)
{
case esriGeometryType.esriGeometryPoint:
pGeometryCol = new MultipointClass() as IGeometryCollection;
flag = 0;
break;
case esriGeometryType.esriGeometryPolygon:
pGeometryCol = new PolygonClass() as IGeometryCollection;
flag = 1;
break;
case esriGeometryType.esriGeometryPolyline:
pGeometryCol = new PolylineClass() as IGeometryCollection;
flag = 1;
break;
}
//IGeometryCollection geocollect = new MultipointClass();
object missing = Type.Missing;
if (flag==0)
{
for (int i = 0; i < featureClass.FeatureCount(null); i++)
{
feature = featureClass.GetFeature(i);
pGeometryCol.AddGeometry(feature.Shape, ref missing, ref missing);
}
}
if (flag==1)
{
for (int i = 0; i < featureClass.FeatureCount(null); i++)
{
feature = featureClass.GetFeature(i);
pGeometryCol.AddGeometryCollection((IGeometryCollection)feature.Shape);
}
}
IHitTest hitTest = pGeometryCol as IHitTest;
double hitDist = 0;
int partIndex = 0;
int vertexIndex = 0;
bool bVertexHit = false;
double tol = convertPixelsToMapUnits(activeView, 8);
if (hitTest.HitTest(point, tol, esriGeometryHitPartType.esriGeometryPartBoundary, hitPoint2, ref hitDist, ref partIndex, ref vertexIndex, ref bVertexHit))
{
hitPoint1 = hitPoint2;
}
axMapControl1.ActiveView.Refresh();
return hitPoint1;
}
public void CreateMarkerElement(IPoint point)
{
IActiveView activeView = axMapControl1.ActiveView;
IGraphicsContainer graphicsContainer = axMapControl1.Map as IGraphicsContainer;
//建立一个marker元素
IMarkerElement markerElement = new MarkerElement() as IMarkerElement;
ISimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbol();
//符号化元素
simpleMarkerSymbol.Color = getRGB(255, 0, 0);
simpleMarkerSymbol.Outline = true;
simpleMarkerSymbol.OutlineColor = getRGB(0, 255, 0) as IColor;
simpleMarkerSymbol.OutlineSize = 5;
simpleMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;
ISymbol symbol = simpleMarkerSymbol as ISymbol;
symbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;
markerElement.Symbol = simpleMarkerSymbol;
m_element = markerElement as IElement;
m_element.Geometry = point as IGeometry;
graphicsContainer.AddElement(m_element, 0);
activeView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, m_element, null);
IGeometry geometry = m_element.Geometry;
movePointFeedback.Display = activeView.ScreenDisplay;
movePointFeedback.Symbol = simpleMarkerSymbol as ISymbol;
movePointFeedback.Start(geometry as IPoint, point);
}
private IRgbColor getRGB(int r, int g, int b)
{
IRgbColor pColor = new RgbColorClass();
pColor.Red = r;
pColor.Green = g;
pColor.Blue = b;
return pColor;
}
//移动元素到新的位置
public void ElementMoveTo(IPoint point)
{
//移动元素
movePointFeedback.MoveTo(point);
IGeometry geometry1 = null;
IGeometry geometry2 = null;
if (m_element != null)
{
geometry1 = m_element.Geometry;
geometry2 = movePointFeedback.Stop();
m_element.Geometry = geometry2;
//更新该元素的位置
axMapControl1.ActiveView.GraphicsContainer.UpdateElement(m_element);
//重新移动元素
movePointFeedback.Stop();
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 activeView, double pixelUnits)
{
double realDisplayExtent;
int pixelExtent;
double sizeOfOnePixel;
pixelExtent = activeView.ScreenDisplay.DisplayTransformation.get_DeviceFrame().right - activeView.ScreenDisplay.DisplayTransformation.get_DeviceFrame().left;
realDisplayExtent = activeView.ScreenDisplay.DisplayTransformation.VisibleBounds.Width;
sizeOfOnePixel = realDisplayExtent / pixelExtent;
return pixelUnits * sizeOfOnePixel;
}
private void button1_Click(object sender, EventArgs e)
{
if (axMapControl1.LayerCount != 0)
{
cbLayerName.Items.Clear();
for (int i = 0; i < axMapControl1.LayerCount; i++)
{
cbLayerName.Items.Add(axMapControl1.get_Layer(i).Name);
}
cbLayerName.Text = cbLayerName.Items[0].ToString();
snapLayer = cbLayerName.Text;
}
else
{
MessageBox.Show("请先加载图层!");
}
}
//更改当前捕捉图层名时
private void cbLayerName_TextChanged(object sender, EventArgs e)
{
snapLayer = cbLayerName.Text;
}