📄 modifyshape.cs
字号:
using System;
using System.Windows.Forms;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.MapControl;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
namespace Cstest1.Class
{
/// <summary>
/// ModifyShape 的摘要说明。
/// </summary>
public class ModifyShape: ITool,ICommand
{
ESRI.ArcGIS.MapControl.AxMapControl m_MapControl; //设置地图控件对象
ESRI.ArcGIS.Carto.ILayer m_CurrentLayer; //获取当前编辑图层
private IDisplayFeedback m_Feedback; //移动图形的拖放对象
private IFeature m_EditFeature; //当前编辑要素
public ModifyShape(ILayer pCurrentLayer)
{
//
// TODO: 在此处添加构造函数逻辑
m_CurrentLayer=pCurrentLayer;
//
}
#region ITool 成员
public void OnMouseDown(int button, int shift, int x, int y)
{
// TODO: 添加 ModifyShape.OnMouseDown 实现
IPoint pHitPoint = null;
double hitDist = 0;
int partIndex = 0;
int vertexIndex = 0;
int vertexOffset = 0;
bool vertex= false;
m_MapControl.Map.ClearSelection();
m_MapControl.ActiveView.Refresh();
SelectMouseDown(x, y); //先调用选择要素方法
IEnumFeature pSelected = (IEnumFeature)m_MapControl.Map.FeatureSelection; //获取选中要素
IFeature pFeature = pSelected.Next();
if (pFeature == null) return;
IActiveView pActiveView = m_MapControl.ActiveView;
IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y); //移动起始点
// 设置捕捉容差
double tol = ConvertPixelsToMapUnits(pActiveView, 4);
//
// while(pFeature != null)
// {
IGeometry pGeom = pFeature.Shape;
IObjectClass pObjectClass = pFeature.Class;
m_EditFeature = pFeature;
switch(pGeom.GeometryType) //根据Geometry类型,移动要素
{
case esriGeometryType.esriGeometryPoint:
m_Feedback = new MovePointFeedback();
m_Feedback.Display = pActiveView.ScreenDisplay;
IMovePointFeedback pPointMove = (IMovePointFeedback)m_Feedback;
pPointMove.Start((IPoint)pGeom, pPoint);
break;
case esriGeometryType.esriGeometryPolyline:
// if (TestGeometryHit(tol, pPoint, pFeature, ref pHitPoint, ref hitDist, ref partIndex, ref vertexIndex, ref vertexOffset, ref vertex))
// {
m_Feedback=new MoveLineFeedbackClass();
m_Feedback.Display = pActiveView.ScreenDisplay;
IMoveLineFeedback m_MoveLineFeedback=(IMoveLineFeedback)m_Feedback;
m_MoveLineFeedback.Start((IPolyline)pGeom,pPoint);
// }
// else
// return;
break;
case esriGeometryType.esriGeometryPolygon:
// if (TestGeometryHit(tol, pPoint, pFeature, ref pHitPoint, ref hitDist, ref partIndex, ref vertexIndex, ref vertexOffset, ref vertex))
// {
m_Feedback=new MovePolygonFeedbackClass();
m_Feedback.Display = pActiveView.ScreenDisplay;
IMovePolygonFeedback m_MovePolygonFeedback=(IMovePolygonFeedback)m_Feedback;
m_MovePolygonFeedback.Start((IPolygon)pGeom,pPoint);
// }
// else
// return;
break;
}
// }
}
public void OnMouseUp(int button, int shift, int x, int y)
{
// TODO: 添加 ModifyShape.OnMouseUp 实现
if (m_Feedback == null) return;
IActiveView pActiveView = m_MapControl.ActiveView;
IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
if (m_Feedback is IMovePointFeedback)
{
IMovePointFeedback pPointMove = (IMovePointFeedback)m_Feedback;
IGeometry pGeometry = pPointMove.Stop();
UpdateFeature(m_EditFeature, pGeometry);
}
else if (m_Feedback is IMoveLineFeedback) //线·对象移动
{
IMoveLineFeedback pLineMove = (IMoveLineFeedback)m_Feedback;
IGeometry pGeometry = pLineMove.Stop();
UpdateFeature(m_EditFeature, pGeometry);
}
else if (m_Feedback is IMovePolygonFeedback) //面·对象移动
{
IMovePolygonFeedback pPolyMove = (IMovePolygonFeedback)m_Feedback;
IGeometry pGeometry = pPolyMove.Stop();
UpdateFeature(m_EditFeature, pGeometry);
}
m_Feedback = null;
pActiveView.Refresh();
}
public void OnKeyDown(int keyCode, int shift)
{
// TODO: 添加 ModifyShape.OnKeyDown 实现
}
public void OnKeyUp(int keyCode, int shift)
{
// TODO: 添加 ModifyShape.OnKeyUp 实现
}
public void OnMouseMove(int button, int shift, int x, int y)
{
// TODO: 添加 ModifyShape.OnMouseMove 实现
// 移动Feedback对象
if (m_Feedback == null) return;
IActiveView pActiveView = m_MapControl.ActiveView;
IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x,y);
m_Feedback.MoveTo(pPoint);
}
public int Cursor
{
get
{
// TODO: 添加 ModifyShape.Cursor getter 实现
return 0;
}
}
public bool OnContextMenu(int x, int y)
{
// TODO: 添加 ModifyShape.OnContextMenu 实现
return false;
}
public bool Deactivate()
{
// TODO: 添加 ModifyShape.Deactivate 实现
return true;
}
public void Refresh(int hdc)
{
// TODO: 添加 ModifyShape.Refresh 实现
}
public void OnDblClick()
{
// TODO: 添加 ModifyShape.OnDblClick 实现
}
#endregion
#region ICommand 成员
public void OnClick()
{
// TODO: 添加 ModifyShape.OnClick 实现
}
public string Message
{
get
{
// TODO: 添加 ModifyShape.Message getter 实现
return null;
}
}
public int Bitmap
{
get
{
// TODO: 添加 ModifyShape.Bitmap getter 实现
return 0;
}
}
public void OnCreate(object hook)
{
// TODO: 添加 ModifyShape.OnCreate 实现
m_MapControl=hook as AxMapControl; //工具创建时,设置地图控件对象
}
public string Caption
{
get
{
// TODO: 添加 ModifyShape.Caption getter 实现
return null;
}
}
public string Tooltip
{
get
{
// TODO: 添加 ModifyShape.Tooltip getter 实现
return null;
}
}
public int HelpContextID
{
get
{
// TODO: 添加 ModifyShape.HelpContextID getter 实现
return 0;
}
}
public string Name
{
get
{
// TODO: 添加 ModifyShape.Name getter 实现
return null;
}
}
public bool Checked
{
get
{
// TODO: 添加 ModifyShape.Checked getter 实现
return false;
}
}
public bool Enabled
{
get
{
// TODO: 添加 ModifyShape.Enabled getter 实现
return false;
}
}
public string HelpFile
{
get
{
// TODO: 添加 ModifyShape.HelpFile getter 实现
return null;
}
}
public string Category
{
get
{
// TODO: 添加 ModifyShape.Category getter 实现
return null;
}
}
#endregion
private void SelectMouseDown(int x, int y) //选择要素(点选方式)
{
IFeatureLayer pFeatureLayer = (IFeatureLayer)m_CurrentLayer;
IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;
if (pFeatureClass == null) return;
IActiveView pActiveView = m_MapControl.ActiveView;
IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
IGeometry pGeometry = pPoint;
double length = ConvertPixelsToMapUnits(pActiveView, 4);
ITopologicalOperator pTopo = (ITopologicalOperator)pGeometry;
IGeometry pBuffer = pTopo.Buffer(length);
pGeometry = (IGeometry)pBuffer.Envelope;
ISpatialFilter pSpatialFilter = new SpatialFilter();
pSpatialFilter.Geometry = pGeometry;
switch(pFeatureClass.ShapeType)
{
case esriGeometryType.esriGeometryPoint:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;
break;
case esriGeometryType.esriGeometryPolyline:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
break;
case esriGeometryType.esriGeometryPolygon:
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
break;
}
pSpatialFilter.GeometryField = pFeatureClass.ShapeFieldName;
IQueryFilter pFilter = pSpatialFilter;
IFeatureCursor pCursor = pFeatureLayer.Search(pFilter, false);
IFeature pFeature = pCursor.NextFeature();
while (pFeature != null)
{
m_MapControl.Map.SelectFeature(m_CurrentLayer, pFeature);
pFeature = pCursor.NextFeature();
}
pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
}
private double ConvertPixelsToMapUnits(IActiveView pActiveView , double pixelUnits)
{
// 依据当前视图,将屏幕像素转换成地图单位
IPoint Point1 = pActiveView.ScreenDisplay.DisplayTransformation.VisibleBounds.UpperLeft;
IPoint Point2 = pActiveView.ScreenDisplay.DisplayTransformation.VisibleBounds.UpperRight;
int x1, x2, y1, y2;
pActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(Point1, out x1, out y1);
pActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(Point2, out x2, out y2);
double pixelExtent = x2 - x1;
double realWorldDisplayExtent = pActiveView.ScreenDisplay.DisplayTransformation.VisibleBounds.Width;
double sizeOfOnePixel = realWorldDisplayExtent / pixelExtent;
return pixelUnits * sizeOfOnePixel;
}
private bool TestGeometryHit(double tolerance, IPoint pPoint, IFeature pFeature, ref IPoint pHitPoint, ref double hitDist, ref int partIndex, ref int vertexIndex, ref int vertexOffset, ref bool vertexHit)
{
// Function returns true if a feature's shape is hit and further defines
// if a vertex lies within the tolorance
bool bRetVal = false;
IGeometry pGeom = (IGeometry)pFeature.Shape;
IHitTest pHitTest = (IHitTest)pGeom;
pHitPoint = new ESRI.ArcGIS.Geometry.Point();
bool bTrue = true;
// 检查顶点是否被点击
if (pHitTest.HitTest(pPoint, tolerance, esriGeometryHitPartType.esriGeometryPartVertex, pHitPoint, ref hitDist, ref partIndex, ref vertexIndex, ref bTrue))
{
bRetVal = true;
vertexHit = true;
}
// 检查边界是否被点击
else if (pHitTest.HitTest(pPoint, tolerance, esriGeometryHitPartType.esriGeometryPartBoundary, pHitPoint, ref hitDist, ref partIndex, ref vertexIndex, ref bTrue))
{
bRetVal = true;
vertexHit = false;
}
// 统计vertexOffset顶点数目
if (partIndex > 0 )
{
IGeometryCollection pGeomColn = (IGeometryCollection)pGeom;
vertexOffset = 0;
for (int i = 0; i < partIndex; i++)
{
IPointCollection pPointColn = (IPointCollection)pGeomColn.get_Geometry(i);
vertexOffset = vertexOffset + pPointColn.PointCount;
}
}
return bRetVal;
}
private void UpdateFeature(IFeature pFeature, IGeometry pGeometry) //修改要素后,更新要素
{
// 检查是否在编辑操作中
IDataset pDataset = (IDataset)pFeature.Class;
IWorkspaceEdit pWorkspaceEdit = (IWorkspaceEdit)pDataset.Workspace;
// 保存当前编辑的要素
pWorkspaceEdit.StartEditOperation();
pFeature.Shape = pGeometry;
pFeature.Store();
pWorkspaceEdit.StopEditOperation();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -