ArcGIS AddIn开发之:属性刷工具

插件地址,相关细节已更新

利用AddIn开发,实现类似PS中仿制图章的工具。即通过鼠标点选的方式,选择一个要素作为源,然后将属性赋值给其他要素。

Tool代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Framework;
using System.Windows.Forms;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Editor;
using System.Drawing;

namespace Brush_Attributes
{
    public class Brush_Attributes : ESRI.ArcGIS.Desktop.AddIns.Tool
    {
        private static AttributeBrushTool_SetPanel m_pbp = null;

        IMap pMap = null;
        //IFeatureLayer pFtlyr = null; //待操作的图层
        IEditor _Editor;

        public Brush_Attributes()
        {
            UID eUID = new UIDClass();
            eUID.Value = "esriEditor.Editor";
            _Editor = ArcMap.Application.FindExtensionByCLSID(eUID) as IEditor;

            if (_Editor.EditState != esriEditState.esriStateEditing)
            {
                Enabled = false;
                return;
            }
            else
            {
                Enabled = true;
            }
        }

        protected override void OnUpdate()
        {
            if (ArcMap.Application != null)
            {
                UID eUID = new UIDClass();
                eUID.Value = "esriEditor.Editor";
                _Editor = ArcMap.Application.FindExtensionByCLSID(eUID) as IEditor;

                if (_Editor.EditState != esriEditState.esriStateEditing)
                {
                    Enabled = false;
                    return;
                }
                else
                {
                    Enabled = true;
                }
            }
        }

        protected override void OnActivate()
        {
            if (Brush_Attributes.m_pbp == null)
            {
                UID windID = new UIDClass();
                windID.Value = ThisAddIn.IDs.AttributeBrushTool_SetPanel;
                IDockableWindow pdw = ArcMap.DockableWindowManager.GetDockableWindow(windID);
                if (!pdw.IsVisible())
                {
                    pdw.Show(true);
                }
            }
        }

        protected override void OnKeyUp(KeyEventArgs arg)
        {
            if (arg.KeyCode == System.Windows.Forms.Keys.Escape)
                ArcMap.Application.CurrentTool = null;
        }

        protected override void OnMouseDown(MouseEventArgs arg)
        {
            if (AttributeBrushTool_SetPanel.cpidLyrId == -1)
                return;

            pMap = ArcMap.Document.FocusMap;
            IActiveView pAv = pMap as IActiveView;
            try
            {
                IPoint tmppnt = new PointClass();
                tmppnt = pAv.ScreenDisplay.DisplayTransformation.ToMapPoint(arg.X, arg.Y);

                ITopologicalOperator ptop = tmppnt as ITopologicalOperator;
                IPolygon tmpPln = ptop.Buffer(0.5) as IPolygon;
                if (AttributeBrushTool_SetPanel.cpidLyrId == -1)
                    return;

                IFeatureClass copiedFtCls = ((IFeatureLayer)pMap.get_Layer(AttributeBrushTool_SetPanel.cpidLyrId)).FeatureClass;

                if (arg.Control && arg.Button == MouseButtons.Left)
                {
                    //设置鼠标样式
                    this.Cursor = System.Windows.Forms.Cursors.Cross;
                    //选择源
                    ISpatialFilter psf = new SpatialFilterClass();
                    psf.Geometry = tmpPln;
                    psf.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

                    IFeatureCursor pFtCursor = copiedFtCls.Search(psf, false); ;
                    IFeature pTmpFt = pFtCursor.NextFeature();
                    if (pTmpFt != null)
                    {
                        //将选择到的要素添加至前端
                        List<string> ss = new List<string>();
                        for (int i = 0; i < pTmpFt.Fields.FieldCount; i++)
                        {
                            switch (pTmpFt.Fields.get_Field(i).Type)
                            {
                                case esriFieldType.esriFieldTypeBlob:
                                case esriFieldType.esriFieldTypeGeometry:
                                case esriFieldType.esriFieldTypeGlobalID:
                                case esriFieldType.esriFieldTypeGUID:
                                case esriFieldType.esriFieldTypeOID:
                                case esriFieldType.esriFieldTypeRaster:
                                    ss.Add("");
                                    break;
                                default:
                                    ss.Add(pTmpFt.get_Value(i).ToString());
                                    break;
                            }
                        }
                        //m_pbp.fillDataGridView3(ss);
                        AttributeBrushTool_SetPanel.fillDataGridView3(ss);
                    }
                }

                else if (arg.Button == MouseButtons.Left)
                {
                    //刷属性
                    //设置鼠标样式
                    Stream sm = this.GetType().Assembly.GetManifestResourceStream("Brush_Attributes.Images.AttributeBrushTool.cur");
                    this.Cursor = new System.Windows.Forms.Cursor(sm);
                    //获取DataGridView中的属性
                    List<string> str = AttributeBrushTool_SetPanel.getDataGridViewValue3();
                    if (str.Count == 0)
                        return;

                    //获取所选择的要素
                    ISpatialFilter psf = new SpatialFilterClass();
                    psf.Geometry = tmpPln;
                    psf.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

                    IFeatureCursor pFtCursor = copiedFtCls.Update(psf, true); ;
                    IFeature pTmpFt = pFtCursor.NextFeature();
                    if (pTmpFt != null)
                    {
                        for (int i = 0; i < pTmpFt.Fields.FieldCount; i++)
                        {
                            if (str[i] != "")
                            {
                                //字段类型转换试试
                                bool goon = true;
                                double d;
                                int ii;

                                switch (pTmpFt.Fields.get_Field(i).Type)
                                {
                                    case esriFieldType.esriFieldTypeDouble:
                                        goon = double.TryParse(str[i], out d);
                                        break;
                                    case esriFieldType.esriFieldTypeInteger:
                                        goon = int.TryParse(str[i], out ii);
                                        break;
                                    default:
                                        break;
                                }
                                if (goon)
                                {
                                    pTmpFt.set_Value(i, str[i]);
                                    pFtCursor.UpdateFeature(pTmpFt);
                                    pFtCursor.Flush();
                                }
                                else
                                {
                                    MessageBox.Show(pTmpFt.Fields.get_Field(i).Name + "字段所输入的值 类型不正确");
                                    return;
                                }
                            }

                        }

                        //刷完属性闪烁要素
                        //FlashShape(pTmpFt);

                        //保存交由编辑器执行
                        //pTmpFt.Store();
                        IFeatureSelection pFtSelection = (IFeatureSelection)((IFeatureLayer)pMap.get_Layer(AttributeBrushTool_SetPanel.cpidLyrId));
                        pFtSelection.Clear();
                        pFtSelection.Add(pTmpFt);
                        pAv.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
                        System.Threading.Thread.Sleep(100);
                        pFtSelection.Clear();
                        System.Threading.Thread.Sleep(100);
                        pAv.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
                        System.Threading.Thread.Sleep(100);
                        pFtSelection.Add(pTmpFt);
                        pAv.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
                    }
                }
                else
                {
                    return;
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("发生未知异常_"+ex.Message);
                return;
            }
        }

        /// <summary>
        /// 要素闪烁
        /// </summary>
        /// <param name="pTmpFt"></param>
        private void FlashShape(IFeature pTmpFt)
        {
            switch (pTmpFt.Shape.GeometryType)
            {
                case esriGeometryType.esriGeometryPoint:
                case esriGeometryType.esriGeometryPolygon:
                case esriGeometryType.esriGeometryPolyline:
                    break;
                default:
                    break;
            }
        }

        protected override void OnMouseMove(MouseEventArgs arg)
        {
            try
            {
                if (arg.Control)
                {
                    //设置鼠标样式
                    this.Cursor = System.Windows.Forms.Cursors.Cross;
                }
                else
                {
                    Stream sm = this.GetType().Assembly.GetManifestResourceStream("Brush_Attributes.Images.AttributeBrushTool.cur");
                    this.Cursor = new System.Windows.Forms.Cursor(sm);
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("发生未知异常_"+ex.Message);
            }
            
        }

        protected override void OnKeyDown(KeyEventArgs arg)
        {
            if (arg.Control)
            {
                //设置鼠标样式
                this.Cursor = System.Windows.Forms.Cursors.Cross;
            }
        }
    }

}

其中,上述代码也实现了在AddIn中自定义鼠标样式。


交互式窗体代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;

namespace Brush_Attributes
{
    /// <summary>
    /// Designer class of the dockable window add-in. It contains user interfaces that
    /// make up the dockable window.
    /// </summary>
    public partial class AttributeBrushTool_SetPanel : UserControl
    {
        IMap pMap = null;
        public static int cpidLyrId=-1;
        internal static AttributeBrushTool_SetPanel _Bsp;

        public AttributeBrushTool_SetPanel(object hook)
        {
            InitializeComponent();
            this.Hook = hook;

            _Bsp = this;
        }

        /// <summary>
        /// Host object of the dockable window
        /// </summary>
        private object Hook
        {
            get;
            set;
        }

        /// <summary>
        /// Implementation class of the dockable window add-in. It is responsible for 
        /// creating and disposing the user interface class of the dockable window.
        /// </summary>
        public class AddinImpl : ESRI.ArcGIS.Desktop.AddIns.DockableWindow
        {
            private AttributeBrushTool_SetPanel m_windowUI;

            public AddinImpl()
            {
            }

            protected override IntPtr OnCreateChild()
            {
                m_windowUI = new AttributeBrushTool_SetPanel(this.Hook);
                return m_windowUI.Handle;
            }

            protected override void Dispose(bool disposing)
            {
                if (m_windowUI != null)
                    m_windowUI.Dispose(disposing);

                base.Dispose(disposing);
            }

        }

        private void cmbLayer_SelectedIndexChanged(object sender, EventArgs e)
        {
            dataGridView1.Rows.Clear();
            pMap = ArcMap.Document.FocusMap;
            //根据选择图层的不同,DataGridView中显示不同的字段名
            if (cmbLayer.SelectedIndex != -1)
            {
                string tmplyrname = cmbLayer.SelectedItem.ToString();
                int tmplyrIndex = getlyridByName(tmplyrname,pMap);
                IFeatureLayer tmpLyr = pMap.get_Layer(tmplyrIndex) as IFeatureLayer;
                cpidLyrId = tmplyrIndex;
                dataGridView1.Rows.Add(tmpLyr.FeatureClass.Fields.FieldCount);
                for (int i = 0; i < tmpLyr.FeatureClass.Fields.FieldCount; i++)
                {
                    dataGridView1[0, i].Value = tmpLyr.FeatureClass.Fields.get_Field(i).Name;
                    switch (tmpLyr.FeatureClass.Fields.get_Field(i).Type)
                    {
                        case esriFieldType.esriFieldTypeGeometry:
                        case esriFieldType.esriFieldTypeRaster:
                        case esriFieldType.esriFieldTypeOID:
                        case esriFieldType.esriFieldTypeGUID:
                        case esriFieldType.esriFieldTypeGlobalID:
                        case esriFieldType.esriFieldTypeBlob:
                            dataGridView1[1, i].ReadOnly = true;
                            dataGridView1[2, i].ReadOnly = true;
                            break;
                        default:
                            DataGridViewCheckBoxCell dgc = ((DataGridViewCheckBoxCell)dataGridView1[1, i]);
                            dgc.Value = true;
                            break;
                    }
                }
            }
        }

        private int getlyridByName(string nm, IMap pMap)
        {
            int id = -1;
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                if (nm == pMap.get_Layer(i).Name)
                {
                    id = i;
                    break;
                }
            }
            return id;
        }

        /// <summary>
        /// 填充第三列,没有则为空
        /// </summary>
        /// <param name="vls"></param>
        public static void fillDataGridView3(List<string> vls)
        {
            try
            {
                for (int i = 0; i < _Bsp.dataGridView1.Rows.Count; i++)
                {
                    DataGridViewCheckBoxCell dgc = (DataGridViewCheckBoxCell)_Bsp.dataGridView1[1, i];
                    if (dgc.Value == null)
                        continue;
                    if ((bool)dgc.Value) //可修改的则赋值
                        _Bsp.dataGridView1[2, i].Value = vls[i];
                }
            }
            catch (System.Exception ex)
            {
                throw new Exception(ex.Message);
            } 
        }

        /// <summary>
        /// 获取第三列的值
        /// </summary>
        /// <returns></returns>
        public static List<string> getDataGridViewValue3()
        {
            List<string> sre = new List<string>();
            try
            {
                for (int i = 0; i < _Bsp.dataGridView1.Rows.Count; i++)
                {
                    DataGridViewCheckBoxCell dgc = (DataGridViewCheckBoxCell)_Bsp.dataGridView1[1, i];
                    if (dgc.Value == null)
                    {
                        sre.Add("");
                        continue;
                    }
                    if ((bool)dgc.Value) //可修改的则赋值
                    {
                        if (_Bsp.dataGridView1[2, i].Value != null)
                            sre.Add(_Bsp.dataGridView1[2, i].Value.ToString());
                        else
                            sre.Add("");
                    }
                }
                return sre;
            }
            catch (System.Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        private void cmbLayer_DropDown(object sender, EventArgs e)
        {
            try
            {
                cmbLayer.Items.Clear();

                IMap tmpMap = ArcMap.Document.FocusMap;
                for (int i = 0; i < tmpMap.LayerCount; i++)
                {
                    IFeatureLayer tmpFtLyr = tmpMap.get_Layer(i) as IFeatureLayer;
                    if (tmpFtLyr != null)
                    {
                        cmbLayer.Items.Add(tmpFtLyr.Name);
                    }
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("发生未知异常_"+ex.Message);
            }
        }

        private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            this.dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
        }
    }
}

工具界面如下。选择待操作图层之后,通过Ctrl+单击,实现属性源的选择。刷否checkebox可以设置属性是否写入目标要素。然后通过单击实现对目标要素属性的写入。



发布了22 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/u012839776/article/details/50118829