《2022年查找属性数据 .pdf》由会员分享,可在线阅读,更多相关《2022年查找属性数据 .pdf(14页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、ArcGIS Engine+C# 实例开发教程第八讲属性数据表的查询显示摘要:这一讲中,我们将实现图层属性数据表的查询显示。在ArcMap 中,单击图层右键菜单中的“ Open Attribute Table”命令,便可弹出属性数据表。本讲将完成类似的功能. 在上一讲中,我们完成了图层符号选择器的制作。这一讲中,我们将实现图层属性数据表的查询显示。在 ArcMap 中,单击图层右键菜单中的“Open Attribute Table ”命令, 便可弹出属性数据表。本讲将完成类似的功能,效果如下:图 1 数据表显示,我们用了DataGridView 控件。 DataGridView 控件提供一种强
2、大而灵活的以表格形式显示数据的方式。可以使用DataGridView 控件来显示少量数据的只读视图,也可以对其进行缩放以显示特大数据集的可编辑视图。我们可以很方便地把一个DataTable 作为数据源绑定到DataGridView 控件中。本讲的思路大体如下:首先根据图层属性中的字段创建一个空的DataTable,然后根据数据内容一行行填充DataTable 数据,再将DataTable 绑定到DataGridView 控件,最后调用并显示属性表窗体。1.创建属性表窗体新建一个Windows 窗体,命名为“AttributeTableFrm.cs ” 。从工具箱拖一个DataGridView
3、控件到窗体,并将其Dock 属性设置为“ Fill” 。添加如下引用:using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.SystemUI; using ESRI.ArcGIS.Geometry; using ESRI.ArcGIS.Geodatabase; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 14 页 - -
4、- - - - - - - 2.创建空 DataTable 首先传入ILayer,再查询到ITable,从 ITable 中的 Fileds 中获得每个Field,再根据Filed 设置DataTable的 DataColumn,由此创建一个只含图层字段的空DataTable。实现函数如下:/ / 根据图层字段创建一个只含字段的空DataTable / / / / private static DataTable CreateDataTableByLayer(ILayer pLayer, string tableName) / 创建一个DataTable表DataTable pDataTabl
5、e = new DataTable(tableName); / 取得 ITable 接口ITable pTable = pLayer as ITable; IField pField = null; DataColumn pDataColumn; / 根据每个字段的属性建立DataColumn 对象for (int i = 0; i pTable.Fields.FieldCount; i+) pField = pTable.Fields.get_Field(i); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 -
6、 - - - - - - 第 2 页,共 14 页 - - - - - - - - - / 新建一个DataColumn 并设置其属性pDataColumn = new DataColumn(pField.Name); if (pField.Name = pTable.OIDFieldName) pDataColumn.Unique = true;/字段值是否唯一 / 字段值是否允许为空pDataColumn.AllowDBNull = pField.IsNullable; / 字段别名pDataColumn.Caption = pField.AliasName; / 字段数据类型pDataC
7、olumn.DataType = System.Type.GetType(ParseFieldType(pField.Type); / 字段默认值pDataColumn.DefaultValue = pField.DefaultValue; / 当字段为String 类型是设置字段长度if (pField.VarType = 8) pDataColumn.MaxLength = pField.Length; / 字段添加到表中pDataTable.Columns.Add(pDataColumn); pField = null; 名师资料总结 - - -精品资料欢迎下载 - - - - - -
8、- - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 14 页 - - - - - - - - - pDataColumn = null; return pDataTable; 因为 GeoDatabase 的数据类型与 .NET的数据类型不同,故要进行转换。转换函数如下:/ / 将 GeoDatabase 字段类型转换成.Net 相应的数据类型/ / 字段类型 / public static string ParseFieldType(esriFieldType fieldType) switch (fieldType) case esri
9、FieldType.esriFieldTypeBlob: return System.String; case esriFieldType.esriFieldTypeDate: return System.DateTime; case esriFieldType.esriFieldTypeDouble: return System.Double; case esriFieldType.esriFieldTypeGeometry: return System.String; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心
10、整理 - - - - - - - 第 4 页,共 14 页 - - - - - - - - - case esriFieldType.esriFieldTypeGlobalID: return System.String; case esriFieldType.esriFieldTypeGUID: return System.String; case esriFieldType.esriFieldTypeInteger: return System.Int32; case esriFieldType.esriFieldTypeOID: return System.String; case es
11、riFieldType.esriFieldTypeRaster: return System.String; case esriFieldType.esriFieldTypeSingle: return System.Single; case esriFieldType.esriFieldTypeSmallInteger: return System.Int32; case esriFieldType.esriFieldTypeString: return System.String; default: return System.String; 3.装载 DataTable数据从上一步得到的
12、DataTable还没有数据,只有字段信息。因此,我们要通过ICursor从 ITable中逐一取出每一行数据,即IRow。再创建DataTable 中相应的DataRow,根据IRow 设置名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 14 页 - - - - - - - - - DataRow 信息,再将所有的DataRow 添加到 DataTable 中,就完成了DataTable数据的装载。为保证效率,一次最多只装载2000 条数据到DataGridView。函
13、数代码如下:/ / 填充 DataTable 中的数据/ / / / public static DataTable CreateDataTable(ILayer pLayer, string tableName) / 创建空 DataTable DataTable pDataTable = CreateDataTableByLayer(pLayer, tableName); / 取得图层类型string shapeType = getShapeType(pLayer); / 创建 DataTable 的行对象DataRow pDataRow = null; / 从 ILayer 查询到 IT
14、able ITable pTable = pLayer as ITable; ICursor pCursor = pTable.Search(null, false); / 取得 ITable 中的行信息IRow pRow = pCursor.NextRow(); int n = 0; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 14 页 - - - - - - - - - while (pRow != null) / 新建 DataTable 的行对象pDataRo
15、w = pDataTable.NewRow(); for (int i = 0; i pRow.Fields.FieldCount; i+) / 如果字段类型为esriFieldTypeGeometry,则根据图层类型设置字段值if (pRow.Fields.get_Field(i).Type = esriFieldType.esriFieldTypeGeometry) pDataRowi = shapeType; / 当图层类型为Anotation 时,要素类中会有esriFieldTypeBlob 类型的数据,/ 其存储的是标注内容,如此情况需将对应的字段值设置为Element else
16、if (pRow.Fields.get_Field(i).Type = esriFieldType.esriFieldTypeBlob) pDataRowi = Element; else pDataRowi = pRow.get_Value(i); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 14 页 - - - - - - - - - / 添加 DataRow 到 DataTable pDataTable.Rows.Add(pDataRow); pDataRow
17、= null; n+; / 为保证效率,一次只装载最多条记录if (n = 2000) pRow = null; else pRow = pCursor.NextRow(); return pDataTable; 上面的代码中涉及到一个获取图层类型的函数getShapeTape , 此函数是通过ILayer 判断图层类型的,代码如下:/ / 获得图层的Shape类型/ / 图层 / 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 14 页 - - - - - - - -
18、- public static string getShapeType(ILayer pLayer) IFeatureLayer pFeatLyr = (IFeatureLayer)pLayer; switch (pFeatLyr.FeatureClass.ShapeType) case esriGeometryType.esriGeometryPoint: return Point; case esriGeometryType.esriGeometryPolyline: return Polyline; case esriGeometryType.esriGeometryPolygon: r
19、eturn Polygon; default: return ; 4.绑定 DataTable到 DataGridView 通 过 以 上 步 骤 , 我 们 已经 得 到 了 一 个 含 有 图 层属 性 数 据 的DataTable。现 定 义 一 个AttributeTableFrm 类的成员变量:public DataTable attributeTable; 通过以下函数,我们很容易将其绑定到DataGridView 控件中。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第
20、9 页,共 14 页 - - - - - - - - - / / 绑定 DataTable 到 DataGridView / / public void CreateAttributeTable(ILayer player) string tableName; tableName = getValidFeatureClassName(player .Name ); attributeTable = CreateDataTable(player,tableName ); this.dataGridView1 .DataSource = attributeTable ; this.Text = 属
21、性表 + tableName + + 记录数: +attributeTable.Rows.Count .ToString(); 因为 DataTable的表名不允许含有“.” ,因此我们用“_”替换。函数如下:/ / 替换数据表名中的点/ / / public static string getValidFeatureClassName(string FCname) int dot = FCname.IndexOf(.); if (dot != -1) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - -
22、 - - - 第 10 页,共 14 页 - - - - - - - - - return FCname.Replace(., _); return FCname; 5.调用属性表窗体通过 1-4 步骤,我们封装了一个AttributeTableFrm 类,此类能够由ILayer 显示图层中的属性表数据。那怎么调用AttributeTableFrm 呢?前面已经提到,我们是在TOCControl 选中图层的右键菜单中弹出属性表窗体的,因此我们需要添加一个菜单项到TOCControl 中 Layer 的右键菜单。而在第六讲中,我们采用的是AE中的 IToolbarMenu 实现右键菜单的,故我们
23、还需自定义一个Command,实现打开属性表的功能。以 ArcGIS的 Base Command 为模板新建项“OpenAttributeTable.cs ” 。注意:新建Base Command 模板时,会弹出一个对话框让我们选择模板适用对象,这时我们要选择 MapControl 、PageLayoutControl,即选择第二项或者倒数第二项。添加如下引用:using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Display; using ESRI.ArcGIS.esriSystem; 添加成员变量:private ILayer m_pLayer; 修改构造
24、函数为:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 14 页 - - - - - - - - - public OpenAttributeTable(ILayer pLayer) / / TODO: Define values for the public properties / base.m_category = ; /localizable text base.m_caption = 打开属性表 ; /localizable text base.m_messa
25、ge = 打开属性表 ; /localizable text base.m_toolTip = 打开属性表 ; /localizable text base.m_name = 打开属性表 ; /unique id, non-localizable (e.g. MyCategory_MyCommand) m_pLayer = pLayer; try / / TODO: change bitmap name if necessary / string bitmapResourceName = GetType().Name + .bmp; base.m_bitmap = new Bitmap(Get
26、Type(), bitmapResourceName); catch (Exception ex) System.Diagnostics.Trace.WriteLine(ex.Message, Invalid Bitmap); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 12 页,共 14 页 - - - - - - - - - 再在 On_Click 函数中添加如下代码,以创建并打开属性表窗体。/ / Occurs when this command is clicked /
27、public override void OnClick() / TODO: Add OpenAttributeTable.OnClick implementation AttributeTableFrm attributeTable = new AttributeTableFrm(); attributeTable.CreateAttributeTable(m_pLayer); attributeTable.ShowDialog(); 至此,我们完成了OpenAttributeTable 命令。显然,我们要在TOCControl 的 OnMouseDown事件中调用此命令。因为,当前选中的图
28、层参数,即ILayer 是通过 OpenAttributeTable 的构造函数传入的,而选中的ILayer 是动态变化的,所以我们无法在窗体初始化的Form1_Load 事件中就添加OpenAttributeTable菜单项到右键菜单。但我们可以在OnMouseDown事件中动态添加OpenAttributeTable 菜单项。要注意的是,最后我们必须移除添加的OpenAttributeTable 菜单项,不然每次按下右键都会添加此菜单项,将造成右键菜单中含有多个OpenAttributeTable 菜单项。修改 TOCControl的 OnMouseDown 事件的部分代码如下:priva
29、te void axTOCControl1_OnMouseDown(object sender, 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 13 页,共 14 页 - - - - - - - - - ITOCControlEvents_OnMouseDownEvent e) / / 弹出右键菜单if (item = esriTOCControlItem.esriTOCControlItemMap) m_menuMap.PopupMenu(e.x, e.y, m_tocContr
30、ol.hWnd); if (item = esriTOCControlItem.esriTOCControlItemLayer) / 动态添加OpenAttributeTable 菜单项m_menuLayer.AddItem(new OpenAttributeTable(layer), -1, 2, true, esriCommandStyles.esriCommandStyleTextOnly); m_menuLayer.PopupMenu(e.x, e.y, m_tocControl.hWnd); / 移除 OpenAttributeTable 菜单项,以防止重复添加m_menuLayer.Remove(2); 6.编译运行按下 F5,编译运行程序,相信你已经实现了开篇处展示的属性表效果了吧!以上代码在Windows XP Sp3 + VS2005 + AE9.2环境下编译通过。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 14 页,共 14 页 - - - - - - - - -