扩展版的Identify工具(附C#源代码)

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Carto;
namespace MyIdentify
{
    public partial class frmIdentify : Form
    {
        private DataTable tdtAttInfo = new DataTable();               //用户记录要素属性值
        private IArray pIdentifyArray;
        private IFeatureIdentifyObj pFeatIdObj;
        private IIdentifyObj pIdObj;
        private IScreenDisplay pScreenDisp;
        private IGeometry pGeometry;
        private ArrayList tempArr = new ArrayList();      //用来记录图层名的数组

        private int mIdentifyID = 0;                      //用来记录当前选择的节点IdentifyID值
       

        public frmIdentify(ref IArray pArray,ref IScreenDisplay pSD,ref IGeometry mGeometry)
        {
            InitializeComponent();
            pIdentifyArray = pArray;
            pScreenDisp = pSD;
            pGeometry = mGeometry;
        }

        private void CreateIdentifyTree()
        {
            treeView1.Nodes.Clear();

            int mTreeNodeName = 0;    //用来记录子节点值,以便点击时获取该值
           
            int mCount = pIdentifyArray.Count;

            TreeNode rNode = new TreeNode();
            for (int i = 0; i < mCount; i++)
            {
                pFeatIdObj = (IFeatureIdentifyObj)pIdentifyArray.get_Element(i);
                pIdObj = (IIdentifyObj)pFeatIdObj;              

                bool bQueryRootNodeLayer = false;   //用来标识是否在临时图层名数组中找到新的节点图层名
               
                TreeNode cNode = new TreeNode();
                foreach (object tempObj in tempArr)
                {
                    if (tempObj.ToString() == pIdObj.Layer.Name)    //如果是子节点
                    {
                        bQueryRootNodeLayer = true;
                        break;
                    }
                }
               
                if (bQueryRootNodeLayer==false)     //没有找到的话,增加根节点,并增加到临时数组中,增加子节点
                {
                    FillAttributeDataTable(ref pIdObj);

                    rNode = new TreeNode();
                    rNode.Text = pIdObj.Layer.Name;
                    treeView1.Nodes.Add(rNode);
                    tempArr.Add(rNode.Text);
                }

                cNode.Text = GetFirsgtStrFieldValue(ref pIdObj);
                cNode.Name = mTreeNodeName.ToString();
                rNode.Nodes.Add(cNode);

                ++mTreeNodeName;
            }


            //显示查询位置
            if (pGeometry.GeometryType == esriGeometryType.esriGeometryPoint)
            {
                txtLocation.Text = "位置XY(" + System.Convert.ToString((System.Math.Round(pGeometry.Envelope.XMin, 3))) + "," + System.Convert.ToString((System.Math.Round(pGeometry.Envelope.YMin, 3))) + ")";
            }

            if (pGeometry.GeometryType == esriGeometryType.esriGeometryEnvelope)
            {
                txtLocation.Text = "位置XY:左下角(" + System.Convert.ToString((System.Math.Round(pGeometry.Envelope.XMin, 3))) + "," + System.Convert.ToString((System.Math.Round(pGeometry.Envelope.YMin, 3))) + "),右下角(" + System.Convert.ToString((System.Math.Round(pGeometry.Envelope.XMax, 3))) + "," + System.Convert.ToString((System.Math.Round(pGeometry.Envelope.YMax, 3))) + ")";
            }

            //显示找到的要素数
            txtFeatures.Text = "共找到" + mCount.ToString() + "个要素";

        }

        //获得Identify对象第一个字符类型字段的值;否则,返回FID的值
        private string GetFirsgtStrFieldValue(ref IIdentifyObj mIdObj)
        {
            string strIdentify;
            IRowIdentifyObject pRowIdObj= (IRowIdentifyObject)mIdObj;

            int mCount = pRowIdObj.Row.Fields.FieldCount;
           
            for (int i = 0; i < mCount; i++)
            {
                IField pField = pRowIdObj.Row.Fields.get_Field(i);

                if (pField.Type == esriFieldType.esriFieldTypeString)
                {
                    strIdentify = pRowIdObj.Row.get_Value(i).ToString();
                    return strIdentify;
                }
            }

            return pRowIdObj.Row.Fields.get_Field(0).ToString();   //返回FID值
        }


        //下面的函数根据IRowIdentifyObject对象来显示属性信息到datagridView
        private void FillAttributeDataTable(ref IIdentifyObj mIdObj)
        {
            tdtAttInfo.Clear();

            IRowIdentifyObject pRowIdObj;
            pRowIdObj = (IRowIdentifyObject)mIdObj;

            int  mCount=pRowIdObj.Row.Fields.FieldCount;
            string strField;
            for (int i = 0; i < mCount; i++)
            {
                IField pField=pRowIdObj.Row.Fields.get_Field(i);
                string strFieldName=pField.Name.ToUpper();

                try
                {
                    if (strFieldName != "FID" && strFieldName != "OBJECTID" && strFieldName != "SHAPE" && strFieldName !="AREA")   //不显示系统字段
                    {
                        strField = strFieldName +","+ pRowIdObj.Row.get_Value(i).ToString();

                        if (strField.Length>0)
                            CreateNewRowforFieldInfo(strField);
                    }
                }
                catch
                {
                }
            }

            return;

        }
       
       
        //新增一条字段值
        void CreateNewRowforFieldInfo(string str)  
        {
            //Create a DataRow based on the DataTable
            DataRow ARow = tdtAttInfo.NewRow();

                //下面使用split函数来分割字符串
                string[] arrFieldInfo = str.Split(',');
                ARow["字段名"] = arrFieldInfo[0];
                ARow["字段值"] = arrFieldInfo[1];

                //已经增加所有的值进了DataRow,现在增加row到DataTable
                tdtAttInfo.Rows.Add(ARow);
        }


        //下面的方法用来初始化GridView控件
        private void InitGridViewControl()
        {
            //初始化gdvConnInfo

            //定义dgvConnInfo列表题名称
            tdtAttInfo.Columns.Add(getNewColumn("字段名", "System.String"));
            tdtAttInfo.Columns.Add(getNewColumn("字段值", "System.String"));
                    
            dgvAttribute.ColumnCount = 2;
            DataGridViewCellStyle styleConnInfo = dgvAttribute.ColumnHeadersDefaultCellStyle;

            //style.BackColor = Color.BlueViolet;
            styleConnInfo.ForeColor = Color.Black;
            styleConnInfo.Font = new Font(dgvAttribute.Font, FontStyle.Regular);

            dgvAttribute.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
            dgvAttribute.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Raised;
            dgvAttribute.CellBorderStyle = DataGridViewCellBorderStyle.Single;
            dgvAttribute.GridColor = SystemColors.ActiveBorder;
            dgvAttribute.RowHeadersVisible = false;
            dgvAttribute.EditMode = DataGridViewEditMode.EditOnEnter;
            //dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            //dgvAttribute.MultiSelect = false;
            dgvAttribute.BackgroundColor = Color.Honeydew;

            dgvAttribute.DataSource = tdtAttInfo;
            //Hide some columns we're not interested in
            for (int i = 0; i < 2; i++)
            {
                dgvAttribute.Columns[i].Visible = false;
            }

            //设置字段名列为只读
            dgvAttribute.Columns["字段名"].DefaultCellStyle.ForeColor = System.Drawing.Color.Black;
            dgvAttribute.Columns["字段名"].ReadOnly = true;        
        }

        //生成DataColumn列
        private DataColumn getNewColumn(string ColName, string ColType)
        {
            //This function simply creates a new column to be used in the DataTable
            DataColumn dc = new DataColumn();
            dc.ColumnName = ColName;
            dc.DataType = System.Type.GetType(ColType);
            return dc;
        }

        private void frmIdentify_Load(object sender, EventArgs e)
        {
            //注意:InitGridViewControl()函数放在此处用来初始化DGV控件,去除第一列空白列和设置字段名列为只读
            InitGridViewControl();
            CreateIdentifyTree();
        }

        private void treeView1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                treeView1.SelectedNode = treeView1.GetNodeAt(e.X, e.Y);
            }

            if (treeView1.SelectedNode.Name != "")
            {

                btnOk.Enabled = false;
               
                mIdentifyID = Convert.ToInt32(treeView1.SelectedNode.Name);
                pFeatIdObj = (IFeatureIdentifyObj)pIdentifyArray.get_Element(mIdentifyID);
                pIdObj = (IIdentifyObj)pFeatIdObj;

                FillAttributeDataTable(ref pIdObj);

                pIdObj.Flash(pScreenDisp);
            }
        }

        private void dgvAttribute_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            btnOk.Enabled = true;
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            ArrayList ArrAttValues = new ArrayList();         //记录tdtAttInfo表中的内容
            foreach (DataRow dtr in tdtAttInfo.Rows)
            {
                ArrAttValues.Add(dtr[0].ToString() + ";" + dtr[1].ToString());
            }

            pFeatIdObj = (IFeatureIdentifyObj)pIdentifyArray.get_Element(mIdentifyID);
          
            pIdObj = (IIdentifyObj)pFeatIdObj;
            IRowIdentifyObject pRowIdObj;
            pRowIdObj = (IRowIdentifyObject)pIdObj;

            IRow pRow = pRowIdObj.Row;
            IFeature pFeature = (IFeature)pRow;

            try
            {

                foreach (string AttributeStr in ArrAttValues)
                {
                    string[] StrArr1 = Regex.Split(AttributeStr, ";");
                    int mIndex=pFeature.Fields.FindField(StrArr1[0]);
                   // MessageBox.Show("index:" + mIndex.ToString() + ";" + StrArr1[1]);
                    IField pField =pFeature.Fields.get_Field(mIndex);

                    if (pField.Editable)
                    {
                        switch (pField.Type)
                        {
                            case esriFieldType.esriFieldTypeString:
                                {
                                    pFeature.set_Value(mIndex, StrArr1[1]);                                   
                                    break;
                                }
                            case esriFieldType.esriFieldTypeInteger:
                                {
                                    pFeature.set_Value(mIndex, Convert.ToInt32(StrArr1[1]));
                                    break;
                                }
                            case esriFieldType.esriFieldTypeDouble:
                                {
                                    pFeature.set_Value(mIndex, Convert.ToDouble(StrArr1[1]));
                                    break;
                                }
                            case esriFieldType.esriFieldTypeSingle:
                                {
                                    pFeature.set_Value(mIndex, Convert.ToSingle(StrArr1[1]));
                                    break;
                                }
                            case esriFieldType.esriFieldTypeDate:
                                {
                                    pFeature.set_Value(mIndex, Convert.ToDateTime(StrArr1[1]));
                                    break;
                                }
                            case esriFieldType.esriFieldTypeSmallInteger:
                                {
                                    pFeature.set_Value(mIndex, Convert.ToInt16(StrArr1[1]));
                                    break;
                                }
                            default:
                                {
                                    pFeature.set_Value(mIndex, Convert.ToInt32(StrArr1[1]));
                                    break;
                                }
                        }
                        pFeature.Store();
                    }
                }
                pFeature.Store();
                btnOk.Enabled = false;
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }

        }      
    }
}

 

调用:

 

// Copyright 2006 ESRI
//
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
//
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
//
// See use restrictions at /arcgis/developerkit/userestrictions.

using System;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Collections.Generic;

using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.esriSystem;
using System.Runtime.InteropServices;

namespace MyIdentify
{
 [ClassInterface(ClassInterfaceType.None)]
    [Guid("DD4DC50B-A06C-496C-A656-56FE1A1B7D62")]

 public class SparkIdentify : ICommand, ITool
 {
        #region COM Registration Function(s)
        [ComRegisterFunction()]
        [ComVisible(false)]
        static void RegisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryRegistration(registerType);

            //
            // TODO: Add any COM registration code here
            //
        }

        [ComUnregisterFunction()]
        [ComVisible(false)]
        static void UnregisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryUnregistration(registerType);

            //
            // TODO: Add any COM unregistration code here
            //
        }

        #region ArcGIS Component Category Registrar generated code
        /// <summary>
        /// Required method for ArcGIS Component Category registration -
        /// Do not modify the contents of this method with the code editor.
        /// </summary>
        private static void ArcGISCategoryRegistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
            ControlsCommands.Register(regKey);

        }
        /// <summary>
        /// Required method for ArcGIS Component Category unregistration -
        /// Do not modify the contents of this method with the code editor.
        /// </summary>
        private static void ArcGISCategoryUnregistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
            ControlsCommands.Unregister(regKey);

        }

        #endregion
        #endregion
  [DllImport("gdi32.dll")]
  static extern bool DeleteObject(IntPtr hObject);

  private System.Drawing.Bitmap m_bitmap;
  private IntPtr m_hBitmap;
  private IHookHelper m_pHookHelper;
  private INewEnvelopeFeedback m_feedBack;
  private IPoint m_point;
  private Boolean m_isMouseDown;
  private System.Windows.Forms.Cursor m_IdentifyCur;
  private System.Windows.Forms.Cursor m_moveIdentifyCur;

        
  public SparkIdentify()
  {
   //Load resources
   string[] res = GetType().Assembly.GetManifestResourceNames();
   if(res.GetLength(0) > 0)
   {
    m_bitmap = new System.Drawing.Bitmap(GetType().Assembly.GetManifestResourceStream(GetType(), "SparkIdentify.bmp"));
    if(m_bitmap != null)
    {
     m_bitmap.MakeTransparent(m_bitmap.GetPixel(1,1));
     m_hBitmap = m_bitmap.GetHbitmap();
    }
   }
   m_pHookHelper = new HookHelperClass();
  }
 
  ~SparkIdentify()
  {
   if(m_hBitmap.ToInt32() != 0)
    DeleteObject(m_hBitmap);
   
   m_pHookHelper = null;
   m_IdentifyCur = null;
            m_moveIdentifyCur = null;

            m_point = null;
  }

  #region ICommand Members

  public void OnClick()
  {
  }

  public string Message
  {
   get
   {
                return "查看和修改可见图层被选中的要素属性信息";
   }
  }

  public int Bitmap
  {
   get
   {
    return m_hBitmap.ToInt32();
   }
  }

  public void OnCreate(object hook)
  {
   m_pHookHelper.Hook = hook;
   m_IdentifyCur = new System.Windows.Forms.Cursor(GetType().Assembly.GetManifestResourceStream(GetType(), "Identify.cur"));
            m_moveIdentifyCur = new System.Windows.Forms.Cursor(GetType().Assembly.GetManifestResourceStream(GetType(), "SparkIdentify.cur"));
     }

        public string Caption
  {
   get
   {
    return "查改属性";
   }
  }

  public string Tooltip
  {
   get
   {
                return "查看和修改可见图层被选中的要素属性信息";
   }
  }

  public int HelpContextID
  {
   get
   {
    // TODO:  Add ZoomIn.HelpContextID getter implementation
    return 0;
   }
  }

  public string Name
  {
   get
   {
    return "SparkIdentify";
   }
  }

  public bool Checked
  {
   get
   {
    return false;
   }
  }

  public bool Enabled
  {
   get
   {
    if(m_pHookHelper.FocusMap == null) return false;
                if (m_pHookHelper.FocusMap.LayerCount == 0) return false;
                if (m_pHookHelper.ActiveView is IPageLayout) return false;
    return true;
   }
  }

  public string HelpFile
  {
   get
   {
    // TODO:  Add ZoomIn.HelpFile getter implementation
    return null;
   }
  }

  public string Category
  {
   get
   {
    return "SparkTools";
   }
  }

  #endregion
 
  #region ITool Members

  public void OnMouseDown(int button, int shift, int x, int y)
  {
   if(m_pHookHelper.ActiveView == null) return;

            //Create a point in map coordinates
            IMap pMap = m_pHookHelper.FocusMap;
            IActiveView pActiveView = (IActiveView)pMap;
   m_point = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
            m_isMouseDown = true;

    }

  public void OnMouseMove(int button, int shift, int x, int y)
  {
   if(!m_isMouseDown) return;

   //Get the focus map
   IActiveView pActiveView = (IActiveView) m_pHookHelper.FocusMap;

   //Start an envelope feedback
   if(m_feedBack == null)
   {
    m_feedBack = new NewEnvelopeFeedbackClass();
    m_feedBack.Display = pActiveView.ScreenDisplay;
    m_feedBack.Start(m_point);
   }

   //Move the envelope feedback
   m_feedBack.MoveTo(pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y));
  }

  public void OnMouseUp(int button, int shift, int x, int y)
  {
   if(!m_isMouseDown) return;

            //Get the focus map
            IMap mMap=m_pHookHelper.FocusMap;
   IActiveView mActiveView = (IActiveView)mMap;
            IScreenDisplay mScreenDisplay=mActiveView.ScreenDisplay;

            IGeometry pGeometry;
            IArray mIDArray=null;

   //If an envelope has not been tracked
   IEnvelope pEnvelope;

   if(m_feedBack == null)
   {
    //以该点Identify   
                mIDArray = GetIdentifyResult(mMap, m_point, mScreenDisplay);
                pGeometry = (IGeometry)m_point;
   }
   else
   {
    //Stop the envelope feedback
    pEnvelope = m_feedBack.Stop();

    //Exit if the envelope height or width is 0
                if (pEnvelope.Width == 0 || pEnvelope.Height == 0)
                {
                    m_feedBack = null;
                    m_isMouseDown = false;
                    mIDArray = GetIdentifyResult(mMap, m_point, mScreenDisplay);
                    pGeometry = (IGeometry)m_point;
                }
                else
                {
                    pGeometry = (IGeometry)pEnvelope;
                    mIDArray = GetIdentifyResult(mMap, pGeometry, mScreenDisplay);
                }
   }           
            m_feedBack = null;
   m_isMouseDown = false;

 


            //显示Identify树目录窗体
            if (mIDArray != null)
            {
                FlashResult(mIDArray, mScreenDisplay);

                frmIdentify fIdentify = new frmIdentify(ref mIDArray, ref mScreenDisplay,ref pGeometry);
                fIdentify.ShowDialog();
            }
    }
      

  public void OnKeyDown(int keyCode, int shift)
  {
   if(m_isMouseDown)
   {
    if(keyCode == 27)
    {
     m_isMouseDown = false;
     m_feedBack = null;
     m_pHookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewForeground, null, null);
    }
   }
  }

  public void OnKeyUp(int keyCode, int shift)
  {
   // TODO:  Add ZoomIn.OnKeyUp implementation
  }

  public int Cursor
  {
   get
   {
    if(m_isMouseDown)
     return m_moveIdentifyCur.Handle.ToInt32();
    else
     return m_IdentifyCur.Handle.ToInt32();
   }
  }
  
  public bool OnContextMenu(int x, int y)
  {
   // TODO:  Add ZoomIn.OnContextMenu implementation
   return false;
  }

  public bool Deactivate()
  {
   return true;
  }

  public void Refresh(int hdc)
  {
   // TODO:  Add ZoomIn.Refresh implementation
  }

  public void OnDblClick()
  {
   // TODO:  Add ZoomIn.OnDblClick implementation
  }
  #endregion


        #region  //获取可见图层的Identify结果集
        private IArray GetIdentifyResult(IMap pMap, IGeometry pGeometry, IScreenDisplay pScreenDisplay)
        {
            IArray pIDArray=null;         
            IIdentify2 pIdentify; 
      
            ILayer mLayer;
            int mLayerCount = pMap.LayerCount;
            for (int i = 0; i < mLayerCount; i++)
            {
                IArray pTempArray = null;

                mLayer = pMap.get_Layer(i);
                if (mLayer.Visible == true)
                {
                    pIdentify = (IIdentify2)mLayer;

                    //将该图层的Identify集元素放入pIDArray中
                    pTempArray = pIdentify.Identify(pGeometry, pScreenDisplay.CancelTracker);
                    if (pTempArray != null)
                    {
                        if (pIDArray != null)
                        {
                            int mCount = pTempArray.Count;
                            for (int j = 0; j < mCount; j++)
                            {
                                pIDArray.Add(pTempArray.get_Element(j));
                            }
                        }
                        else
                        {
                            pIDArray = pTempArray;
                        }
                    }
                }
            }          
              
            return pIDArray;
        }
        #endregion

        #region    //闪烁查找结果
        private void FlashResult(IArray pIDArray, IScreenDisplay pScreenDisplay)
        {
            int mCount = pIDArray.Count;
            IFeatureIdentifyObj pFeatIdObj;
            IIdentifyObj pIdObj;

            for (int i = 0; i < mCount; i++)
            {
                pFeatIdObj = (IFeatureIdentifyObj)pIDArray.get_Element(i);
                pIdObj = (IIdentifyObj)pFeatIdObj;
                pIdObj.Flash(pScreenDisplay);
            }
        }
        #endregion

    }
}

 

posted @ 2009-03-12 15:10  闫磊博客  阅读(847)  评论(0)    收藏  举报