ArcEngine|矢量编辑功能
所有的代码已经传到了我的GitHub,需要的请自取,GitHub项目地址:https://github.com/Weltra/T_ArcMap
(1)界面设计
窗体中包括要素图层下拉菜单、开始/结束/保存编辑按钮、要素选择和移动工具、创建点/线/面要素工具,以及窗体最下方的“当前使用工具”的提示文字。
(2)实现思路:
根据workspace和map开启编辑,设置目标图层,设置编辑操作的任务类型。激活对应的Tool,在AxMapControl中画图形,添加要素。
(3)代码
窗体部分
public EditVectorForm()
{
InitializeComponent();
}
public EditVectorForm(AxMapControl mapControl)
: this()
{
this._editParameter = new EditParameter(mapControl);
this._initializeLayer(this._editParameter.iMapCtrl);
this.initializeTools();
}
private List<IFeatureLayer> FeatureLayers = new List<IFeatureLayer>();
private List<string> NameList = new List<string>();
private void _initializeLayer(IMapControlDefault mapControl)
{
for (int i = 0; i < mapControl.LayerCount; i++)
{
IFeatureLayer tmpLayer = mapControl.Layer[i] as IFeatureLayer;
if (tmpLayer != null)
{
this.FeatureLayers.Add(tmpLayer);
this.NameList.Add(tmpLayer.Name);
}
}
this.cbLayerList.DataSource = this.NameList;
this._editParameter.FeatureLayer = this._getLayerByName(this.cbLayerList.SelectedItem.ToString());
}
private void initializeTools()
{
this.tsbSelectByPoint.Tag = new Tools.Basic.SelectByPoint(this._editParameter);
this.tsbSelectByPolygon.Tag = new Tools.Basic.SelectByPolygon(this._editParameter);
this.tsbMove.Tag = new Tools.Basic.Move(this._editParameter);
this.tsbCreatePoint.Tag = new Tools.Point.Create(this._editParameter);
this.tsbSketchPolygon.Tag = new Tools.Polygon.SketchPolygon(this._editParameter);
this.tsbSketchLine.Tag = new Tools.Polygon.SketchPolygon(this._editParameter);
this.tsbCreateLine.Tag = new Tools.Polyline.CreatePolyline(this._editParameter);
}
private IFeatureLayer _getLayerByName(string layerName)
{
var curLayer = from layer in this.FeatureLayers
where layer.Name == layerName
select layer;
if (curLayer.Count() == 1)
{
return curLayer.ToArray()[0];
}
else
{
return null;
}
}
private void cbLayerList_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.cbLayerList.SelectedItem == null)
{
this.btnEndEdit.Enabled = false;
this.btnSaveEdit.Enabled = false;
this.btnStartEdit.Enabled = false;
}
else
{
this.btnEndEdit.Enabled = true;
this.btnSaveEdit.Enabled = true;
this.btnStartEdit.Enabled = true;
string layerName = this.cbLayerList.SelectedItem.ToString();
this._editParameter.FeatureLayer = this._getLayerByName(layerName);
}
}
private void btnStartEdit_Click(object sender, EventArgs e)
{
EditHelper.StartEditing(this.Parameters.WorkspaceEdit, this.Parameters.FeatureClass, false);
}
private void btnSaveEdit_Click(object sender, EventArgs e)
{
EditHelper.StopEditing(this.Parameters.WorkspaceEdit, true);
}
private void toolStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
BaseTool curTool = e.ClickedItem.Tag as BaseTool;
if (curTool == null)
{
return;
}
else
{
tsl_toolName.Text = curTool.GetType().ToString();
this._editParameter.CurrentTool = curTool;
}
}
private void cbLayerList_SelectedIndexChanged_1(object sender, EventArgs e)
{
}
添加点工具
public override void OnCreate(object hook)
{
try
{
m_hookHelper = new HookHelperClass();
m_hookHelper.Hook = hook;
if (m_hookHelper.ActiveView == null)
{
m_hookHelper = null;
}
}
catch
{
m_hookHelper = null;
}
if (m_hookHelper == null)
base.m_enabled = false;
else
base.m_enabled = true;
}
/// <summary>
/// Occurs when this tool is clicked
/// </summary>
public override void OnClick()
{
}
public override void OnMouseDown(int Button, int Shift, int X, int Y)
{
IMapControlDefault mapControl = this.m_hookHelper.Hook as IMapControlDefault;
if (mapControl != null && _para.FeatureClass != null)
{
_para.WorkspaceEdit.StartEditOperation();
IPoint point = mapControl.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
IFeature temptFeature = _para.FeatureClass.CreateFeature();
double tmpX = point.X;
double tmpY = point.Y;
temptFeature.Shape = point;
temptFeature.Store();
mapControl.ActiveView.Refresh();
_para.WorkspaceEdit.StopEditOperation();
}
}
添加线工具
private IHookHelper m_hookHelper = null;
private TArcMap.Edit.EditParameter _para;
public TArcMap.Edit.EditParameter EditingParameter
{
get { return this._para; }
set { this._para = value; }
}
public CreatePolyline()
{
//
// TODO: Define values for the public properties
//
base.m_category = ""; //localizable text
base.m_caption = ""; //localizable text
base.m_message = "This should work in ArcMap/MapControl/PageLayoutControl"; //localizable text
base.m_toolTip = ""; //localizable text
base.m_name = ""; //unique id, non-localizable (e.g. "MyCategory_MyTool")
try
{
//
// TODO: change resource name if necessary
//
string bitmapResourceName = GetType().Name + ".bmp";
base.m_bitmap = new Bitmap(GetType(), bitmapResourceName);
base.m_cursor = new System.Windows.Forms.Cursor(GetType(), GetType().Name + ".cur");
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");
}
}
public CreatePolyline(TArcMap.Edit.EditParameter paras)
: this()
{
this._para = paras;
}
#region Overridden Class Methods
/// <summary>
/// Occurs when this tool is created
/// </summary>
/// <param name="hook">Instance of the application</param>
public override void OnCreate(object hook)
{
try
{
m_hookHelper = new HookHelperClass();
m_hookHelper.Hook = hook;
if (m_hookHelper.ActiveView == null)
{
m_hookHelper = null;
}
}
catch
{
m_hookHelper = null;
}
if (m_hookHelper == null)
base.m_enabled = false;
else
base.m_enabled = true;
// TODO: Add other initialization code
}
/// <summary>
/// Occurs when this tool is clicked
/// </summary>
public override void OnClick()
{
// TODO: Add CreatePolyline.OnClick implementation
}
public override void OnMouseDown(int Button, int Shift, int X, int Y)
{
IMapControlDefault mapControl = this.m_hookHelper.Hook as IMapControlDefault;
IPolygon polyline = mapControl.TrackLine() as IPolygon;
if (_para.FeatureClass != null)
{
_para.WorkspaceEdit.StartEditOperation();
IFeature newFeature = _para.FeatureClass.CreateFeature();
newFeature.Shape = polyline as IGeometry;
newFeature.Store();
_para.WorkspaceEdit.StopEditOperation();
}
}
public override void OnMouseMove(int Button, int Shift, int X, int Y)
{
// TODO: Add CreatePolyline.OnMouseMove implementation
}
public override void OnMouseUp(int Button, int Shift, int X, int Y)
{
// TODO: Add CreatePolyline.OnMouseUp implementation
}
#endregion
编辑面的折点
public override void OnClick()
{
this._para.MapCtrl.OnAfterDraw += new IMapControlEvents2_Ax_OnAfterDrawEventHandler(_mapCtrl_OnAfterDraw);
_para.SelectedFeatures = TArcMap.Edit.EditHelper.GetSelectedFeatures(_para.FeatureLayer);
if (this._para.SelectedFeatures == null)
{
return;
}
else if (this._para.SelectedFeatures.Count > 0)
{
_para.CurrentFeature = _para.SelectedFeatures[0];
_para.CurrentGeomtry = _para.SelectedFeatures[0].Shape;
//触发对geometry的绘制。
}
else
{
return;
}
_para.MapCtrl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewForeground, null, null);
}
private bool _mouseDown = false;
private IPoint _startPoint;
private IPolygonMovePointFeedback _polygonDisplayFeedback;
public override void OnMouseDown(int Button, int Shift, int X, int Y)
{
this._mouseDown = true;
if (vetexIndex >= 0)
{
_startPoint = this._para.iMapCtrl.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
_polygonDisplayFeedback = new PolygonMovePointFeedbackClass();
_polygonDisplayFeedback.Display = this._para.iMapCtrl.ActiveView.ScreenDisplay;
_polygonDisplayFeedback.Start(_para.CurrentGeomtry as IPolygon, vetexOffset + vetexIndex, this._startPoint);
}
}
int vetexOffset = -1;
int vetexIndex = -1;
int segmentIndex = -1;
public override void OnMouseMove(int Button, int Shift, int X, int Y)
{
//鼠标没有点下去,只修改mouse cursor。
if (this._mouseDown == false)
{
IPoint mousePoint = this._para.iMapCtrl.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
bool hitVetexResult = TArcMap.Edit.EditHelper.GetVertexByPoint(this._para.MapCtrl, mousePoint, this._para.SelectedFeatures[0].Shape, ref vetexOffset, ref vetexIndex);
bool hitBoundaryResult = TArcMap.Edit.EditHelper.GetSegmentByPoint(this._para.MapCtrl, mousePoint, this._para.SelectedFeatures[0].Shape, ref segmentIndex);
if (hitVetexResult)
{
IMapControlDefault iMapCtrl = this.m_hookHelper.Hook as IMapControlDefault;
System.Windows.Forms.Cursor vetexMove = new System.Windows.Forms.Cursor(Properties.Resources.VetexMove.Handle);
this.m_cursor = vetexMove;
}
//else if (hitBoundaryResult)
//{
// IMapControlDefault iMapCtrl = this.m_hookHelper.Hook as IMapControlDefault;
// System.Windows.Forms.Cursor vetexMove = new System.Windows.Forms.Cursor(Properties.Resources.SegmentMove.Handle);
// this.m_cursor = vetexMove;
//}
else
{
this.m_cursor = null;
}
}
//如果鼠标按下,则开始移动节点或者Segment。
else if (this._mouseDown == true)
{
if (this._polygonDisplayFeedback != null)
{
IPoint curPoint = this._para.iMapCtrl.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
this._polygonDisplayFeedback.MoveTo(curPoint);
}
}
}
public override void OnMouseUp(int Button, int Shift, int X, int Y)
{
if (this._mouseDown == true)
{
if (this._polygonDisplayFeedback != null)
{
IPolygon endPolygon = this._polygonDisplayFeedback.Stop();
this._para.CurrentFeature.Shape = endPolygon;
this._para.CurrentFeature.Store();
this._para.iMapCtrl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
}
}
this._mouseDown = false;
}