namespace 捕捉
{
public partial class Form1 : Form
{
private bool bCreateElement=true;
private int internalTime = 5;
private int snapTime = 10;
private IElement m_element = null;
IPoint currentPoint=new PointClass();
private IPoint snapPoint = null;
IMovePointFeedback movePointFeedback=new MovePointFeedbackClass();
private string snapLayer = "";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void axMapControl1_OnMouseMove(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseMoveEvent e)
{
currentPoint.PutCoords(e.mapX,e.mapY);
snapTime++;
snapTime = snapTime%internalTime;
ILayer layer=GetLayerByName(snapLayer,axMapControl1);
if (layer==null)
{
return;
}
IFeatureLayer featureLayer = layer as IFeatureLayer;
if (bCreateElement)
{
CreateMarkerElement(currentPoint);
bCreateElement = false;
}
if (snapPoint==null)
{
ElementMoveTo(currentPoint);
}
if (snapTime==0)
{
#region 第一种捕捉方式
IPoint temPoint = new PointClass();
temPoint.X = e.mapX;
temPoint.Y = e.mapY;
snapPoint = GetNearestVertex(axMapControl1.ActiveView, temPoint, 8);
#endregion
#region 第二种方式
//snapPoint = Snapping(e.mapX, e.mapY, featureLayer);
#endregion
}
if (snapPoint!=null&&snapTime==0)
{
ElementMoveTo(snapPoint);
}
}
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;
}
public IPoint Snapping(double x,double y,IFeatureLayer featureLayer)
{
#region 这种捕捉有问题,无法捕捉点和面图层
IPoint iHitPoint = null;
IMap iMap = axMapControl1.Map;
IActiveView iView = axMapControl1.ActiveView;
IFeatureClass iFClass = featureLayer.FeatureClass;
IPoint point=new PointClass();
point.PutCoords(x,y);
double length = ConvertPixelsToMapUnits(iView, 8);
ITopologicalOperator pTopo = point as ITopologicalOperator;
IGeometry pGeometry = pTopo.Buffer(length).Envelope as IGeometry;
ISpatialFilter spatialFilter=new SpatialFilterClass();
spatialFilter.GeometryField = featureLayer.FeatureClass.ShapeFieldName;
spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
spatialFilter.Geometry = pGeometry;
IFeatureCursor cursor = iFClass.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;
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;
#endregion
}
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;
this.axMapControl1.ActiveView.GraphicsContainer.UpdateElement(m_element);
movePointFeedback.Start(geometry1 as IPoint,point);
axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics,null,null);
}
}
public IPoint GetNearestVertex(IActiveView actview, IPoint pnt, double mapSize)
{
IPoint vetex = null;
IPoint hitPnt = new PointClass();
IHitTest hitTest = null;
IPointCollection pntColl = new MultipointClass();
IProximityOperator prox = null;
double hitdis = 0;
int hitpartindex = 0;
int hitsegindex = 0;
Boolean rside = false;
IFeatureCache2 featCache = new FeatureCacheClass();
double pixelSize = ConvertPixelsToMapUnits(actview, mapSize); //将地理范围转化为像素
featCache.Initialize(pnt, pixelSize); //初始化缓存
for (int i = 0; i < actview.FocusMap.LayerCount; i++)
{
//只有点、线、面并且可视的图层才加入缓存
IFeatureLayer featLayer = (IFeatureLayer)actview.FocusMap.get_Layer(i);
if (featLayer != null && featLayer.Visible == true &&
(featLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline ||
featLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPolygon ||
featLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPoint))
{
featCache.AddFeatures(featLayer.FeatureClass, null);
for (int j = 0; j < featCache.Count; j++)
{
IFeature feat = featCache.get_Feature(j);
hitTest = (IHitTest)feat.Shape;
//捕捉节点,另外可以设置esriGeometryHitPartType,捕捉边线点,中间点等。
if (hitTest.HitTest(pnt, mapSize, esriGeometryHitPartType.esriGeometryPartVertex, hitPnt, ref hitdis, ref hitpartindex, ref hitsegindex, ref rside))
{
object obj = Type.Missing;
pntColl.AddPoint(hitPnt, ref obj, ref obj);
break;
}
}
}
}
prox = (IProximityOperator)pnt;
double minDis = 0, dis = 0;
for (int i = 0; i < pntColl.PointCount; i++)
{
IPoint tmpPnt = pntColl.get_Point(i);
dis = prox.ReturnDistance(tmpPnt);
if (i == 0)
{
minDis = dis;
vetex = tmpPnt;
}
else
{
if (dis < minDis)
{
minDis = dis;
vetex = tmpPnt;
}
}
}
return vetex;
}
public ILayer GetLayerByName(string layerName, AxMapControl axMap)
{
for (int i = 0; i < axMap.LayerCount; i++)
{
if (axMap.get_Layer(i).Name.EndsWith(layerName))
{
return axMap.get_Layer(i);
}
}
return null;
}
public void CreateMarkerElement(IPoint point)
{
IActiveView activeView = this.axMapControl1.ActiveView;
IGraphicsContainer graphicsContainer = axMapControl1.Map as IGraphicsContainer;
IMarkerElement markerElement = new MarkerElement() as IMarkerElement;
ISimpleMarkerSymbol simpleMarkerSymbol=new SimpleMarkerSymbol();
IRgbColor rgbColor1=new RgbColor();
rgbColor1.Red = 0;
rgbColor1.Blue = 100;
rgbColor1.Green = 255;
simpleMarkerSymbol.Color = rgbColor1;
IRgbColor iRgbColor2=new RgbColor();
iRgbColor2.Red = 0;
iRgbColor2.Blue = 0;
iRgbColor2.Green = 0;
simpleMarkerSymbol.Outline = true;
simpleMarkerSymbol.OutlineColor = iRgbColor2 as IColor;
simpleMarkerSymbol.OutlineSize = 1;
simpleMarkerSymbol.Size = 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 void cbLayerName_SelectedIndexChanged(object sender, EventArgs e)
{
snapLayer = cbLayerName.Text;
}
private void Form1_DoubleClick(object sender, EventArgs e)
{
}
private void splitContainer1_Panel2_DoubleClick(object sender, EventArgs e)
{
for (int i = 0; i < axMapControl1.Map.LayerCount; i++)
{
cbLayerName.Items.Add(axMapControl1.get_Layer(i).Name);
}
cbLayerName.Text = cbLayerName.Items[0].ToString();
snapLayer = cbLayerName.Text;
}
}
}
请发表评论