GIS二次开发实验指导书(8)

更新时间:2023-10-24 02:20:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

实验八 打开属性表

一、实验目的

通过创建ClassOpenAttributeTable类及其方法实现打开属性表的功能,掌握表、字段等接口的使用。 二、实验设备与软件环境

计算机;

VS2010、AE。 三、实验内容

通过创建ClassOpenAttributeTable类及其CreateDataTableByLayer、GetShapeType方法,在图层树控件中显示图层,并根据图层的弹出式菜单调用ClassOpenAttributeTable类的方法来打开属性表。 四、实验步骤

1、新建项目,设置项目保存位置和项目名称。

2、在项目中添加MapControl、TOCControl、ToolbarControl、LicenseControl和contextMenuStrip控件,并进行布局,如下图所示。

3、在contextMenuStrip中添加“打开属性表”菜单。

4、添加新窗体,用于显示所选图层的属性表。

5、在新窗体中添加控件dataGridView,布局,并重新定义构造函数。

DataTable objDataTable;

IMapControl3 objMapControl; ILayer objLayer;

public FormAttributeTable(DataTable pDataTable, IMapControl3 pMapControl, ILayer pLayer)//带参数的构造函数 {

InitializeComponent(); objDataTable = pDataTable; objMapControl = pMapControl; objLayer = pLayer; }

3、项目中添加新的类,命名为ClassOpenAttributeTable。

4、在ClassOpenAttributeTable类中建立构造函数。 public ClassOpenAttributeTable() {

}

5、在ClassOpenAttributeTable类中建立自定义方法CreateDataTableByLayer。

public DataTable CreateDataTableByLayer(ILayer pLayer, string tableName) {

//创建一个DataTable表

DataTable pDataTable = new DataTable(tableName);

//取得ITable接口

ITable pTable = pLayer as ITable; IField pField = null;

DataColumn pDataColumn;//System.Data.DataTable中列

//根据每个字段的属性建立DataColumn对象

for (int i = 0; i < pTable.Fields.FieldCount; i++) {

pField = pTable.Fields.get_Field(i);

//新建一个DataColumn并设置其属性

pDataColumn = new DataColumn(pField.Name);

if (pField.Name == pTable.OIDFieldName)//此列的每行须唯一 {

pDataColumn.Unique = true;//字段值是否唯一 }

//字段值是否允许为空

pDataColumn.AllowDBNull = pField.IsNullable;

//字段别名

pDataColumn.Caption = pField.AliasName;

//字段数据类型

pDataColumn.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;

pDataColumn = null; }

//取得图层类型

string shapeType = GetShapeType(pLayer);

//创建DataTable的行对象 DataRow pDataRow = null;

ICursor pCursor = pTable.Search(null, false);

//取得ITable中的行信息

IRow pRow = pCursor.NextRow();

while (pRow != null) {

//新建DataTable的行对象

pDataRow = pDataTable.NewRow();

for (int i = 0; i < pRow.Fields.FieldCount; i++) {

//如果字段类型为esriFieldTypeGeometry,则根据图层类型设置字段值

if (pRow.Fields.get_Field(i).Type == esriFieldType.esriFieldTypeGeometry) {

pDataRow[i] = shapeType; }

//当图层类型为Anotation时,要素类中会有esriFieldTypeBlob类型的数据, //其存储的是标注内容,如此情况需将对应的字段值设置为Element else if (pRow.Fields.get_Field(i).Type == esriFieldType.esriFieldTypeBlob) {

pDataRow[i] = \; } else {

pDataRow[i] = pRow.get_Value(i); } }

//添加DataRow到DataTable

pDataTable.Rows.Add(pDataRow); pDataRow = null;

pRow = pCursor.NextRow(); }

return pDataTable; }

6、在ClassOpenAttributeTable类中建立自定义方法GetShapeType。

private string GetShapeType(ILayer pLayer) {

IFeatureLayer pFeatLyr = (IFeatureLayer)pLayer; switch (pFeatLyr.FeatureClass.ShapeType) {

case esriGeometryType.esriGeometryPoint: return \;

case esriGeometryType.esriGeometryPolyline: return \;

case esriGeometryType.esriGeometryPolygon: return \; default:

return \; } }

7、在ClassOpenAttributeTable类中建立自定义方法ParseFieldType。 private string ParseFieldType(esriFieldType fieldType) {

switch (fieldType) {

case esriFieldType.esriFieldTypeBlob: return \;

case esriFieldType.esriFieldTypeDate: return \;

case esriFieldType.esriFieldTypeDouble: return \;

case esriFieldType.esriFieldTypeGeometry: return \;

case esriFieldType.esriFieldTypeGlobalID: return \;

case esriFieldType.esriFieldTypeGUID: return \;

case esriFieldType.esriFieldTypeInteger: return \;

case esriFieldType.esriFieldTypeOID: return \;

case esriFieldType.esriFieldTypeRaster: return \;

case esriFieldType.esriFieldTypeSingle: return \;

case esriFieldType.esriFieldTypeSmallInteger: return \;

case esriFieldType.esriFieldTypeString: return \;

default:

return \; } }

8、在ClassOpenAttributeTable类中建立自定义方法GetValidLayerName。

public string GetValidLayerName(string strLayerName)//图层名称不能为\ {

int dot = strLayerName.IndexOf(\); if (dot != -1) {

return strLayerName.Replace(\, \); }

return strLayerName; }

9、在主窗体的contextMenuStrip控件的“打开属性表”按钮中添加如下代码: private void MenuOpenTabel_Click(object sender, EventArgs e) {

IBasicMap objMap = new MapClass();

ILayer objLayer = new FeatureLayerClass(); object objOther = new object(); object objIndex = new object();

esriTOCControlItem objItem = new esriTOCControlItem(); try {

axTOCControl1.GetSelectedItem(ref objItem, ref objMap, ref objLayer, ref objOther, ref objIndex);

} catch {

MessageBox.Show(\获取选择图层类型错误!\, \错误\, MessageBoxButtons.OK, MessageBoxIcon.Error); }

DataTable objDataTable = null;

if (objItem == esriTOCControlItem.esriTOCControlItemLayer)//在图层中弹出右键菜单 {

ClassOpenAttributeTable objClassOpenAttributeTable = new ClassOpenAttributeTable();

objDataTable = objClassOpenAttributeTable.CreateDataTableByLayer(objLayer, objClassOpenAttributeTable.GetValidLayerName(objLayer.Name)); }

foreach (Form openForm in Application.OpenForms)

{

if (openForm.Name.Equals(\)) {

openForm.Close(); break; } }

IMapControl3 pMapControl = axMapControl1.Object as IMapControl3;

FormAttributeTable objForm = new FormAttributeTable(objDataTable, pMapControl, objLayer);

objForm.Show(); }

10、在axTOCControl的OnMouseDown事件中添加如下代码。 if (e.button == 2) {

IBasicMap objMap = new MapClass();

ILayer objLayer = new FeatureLayerClass(); object objOther = new object(); object objIndex = new object();

esriTOCControlItem objItem = new esriTOCControlItem(); try {

axTOCControl1.HitTest(e.x, e.y, ref objItem, ref objMap, ref objLayer, refobjOther, ref objIndex);

}

catch {

MessageBox.Show(\弹出右键菜单错误!\, \错误\, MessageBoxButtons.OK, MessageBoxIcon.Error); }

if (objItem == esriTOCControlItem.esriTOCControlItemMap)//在地图上弹出右键菜单

{

}

if (objItem == esriTOCControlItem.esriTOCControlItemLayer)//在图层中弹出右键菜单

{

//显示右键菜单

contextMenuStrip1.Show(axTOCControl1, e.x, e.y); }

}

11、在弹出窗体的load事件中添加如下代码。

private void FormAttributeTable_Load(object sender, EventArgs e) {

dataGridView1.DataSource = objDataTable;

this.Text = \ + objDataTable.TableName + \属性表\;

//dataGridView默认加载时为全部选中记录,需取消选择 IMap pMap = objMapControl.ActiveView.FocusMap; pMap.ClearSelection(); }

12、在dataGridView的SelectionChanged事件中添加如下代码,实现属性表与地图同步。 private void dataGridView1_SelectionChanged(object sender, EventArgs e) {

try {

IMap pMap;

pMap = objMapControl.ActiveView.FocusMap; IActiveView pActiveView;

pActiveView = (IActiveView)pMap; pMap.ClearSelection(); pActiveView.Refresh();

IQueryFilter pQueryFilter = new QueryFilterClass(); IFeatureLayer pFeatureLayer;

pFeatureLayer = (IFeatureLayer)objLayer; IFields pFields;

pFields = pFeatureLayer.FeatureClass.Fields; IField pField;

pField = pFields.get_Field(0); string sid;

for (int i = 0; i < dataGridView1.SelectedRows.Count; i++) {

sid = dataGridView1.SelectedRows[i].Index.ToString(); if (i == 0) {

pQueryFilter.WhereClause = (pField.Name).ToString() + \ + sid; } else {

pQueryFilter.WhereClause += \ + (pField.Name).ToString() + \+ sid;

} }

IFeatureCursor pFeatureCursor;

pFeatureCursor = pFeatureLayer.FeatureClass.Search(pQueryFilter, false); IFeature pFeatrue = pFeatureCursor.NextFeature(); while (pFeatrue != null) {

pMap.SelectFeature(pFeatureLayer, pFeatrue); pFeatrue = pFeatureCursor.NextFeature(); }

pActiveView.Refresh(); } catch {

MessageBox.Show(\地图同步显示出错!\, \错误\, MessageBoxButtons.OK, MessageBoxIcon.Error); } }

13、程序运行结果如下。

五、思考题:

1、C#中的接口和类有什么异同?

2、break、continue、goto和return有什么区别?

本文来源:https://www.bwwdw.com/article/7oy2.html

Top