扩展版的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
}
}