ArcEngine|实现矢量编辑功能

发布时间 2023-06-09 15:42:54作者: Weltㅤ

(1)界面设计

窗体中包括要素图层下拉菜单、开始/结束/保存编辑按钮、要素选择和移动工具、创建点/线/面要素工具,以及窗体最下方的“当前使用工具”的提示文字。

image-20230609152214681

(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;
}

结果展示

打开编辑窗口

image-20230421205721120

添加点

image-20230421205753325

按范围选择

image-20230421210432934

编辑面的折点

image-20230421211955429

添加线要素

2023691529