最近在北京出差一直没有时间继续写博客,主要是晚上上网的条件不好,而且和几个同事住在一起也不太方便写博客,因为随时我们都可能聊天交流!今晚还是决定继续写一遍比较简单的博客,就是继续写ArcGIS的项目,今天主要介绍的内容就是关于空间数据完整性、格式等地检查!
1.首先定义一个用于操作的SDE空间数据库的工作空间。
- public IFeatureWorkspace pWorkspaceSDE;//SDE数据库的工作空间
2.加载需要检查的MDB数据库文件。
- //设置默认DBM文件为第一个,并加载它的表到DataGridView
- filenameComboBox.SelectedIndex = 0;
- AddDataToDataGridView(filenameComboBox.SelectedItem.ToString());
第一次加载时默认解析第一个MDB文件里面的数据表,并且把这些表的信息加载到控件中显示。加载对应MDB文件的数据表信息的函数如下所示:
- /// <summary>
- /// 将DBM文件中的表加载到DataGridView中
- /// </summary>
- /// <param name="filename"></param>
- private void AddDataToDataGridView(string filename)
- {
- dataGridViewX1.Rows.Clear();
- //打开mdb文件所在的工作空间
- IWorkspaceFactory wf = new AccessWorkspaceFactory();
- IFeatureWorkspace pFeatureWorkspaceMDB = wf.OpenFromFile(filename, 0) as IFeatureWorkspace;
- IWorkspace pWorkspaceMDB = pFeatureWorkspaceMDB as IWorkspace;
- //1.遍历mdb的每一个要素集
- IEnumDataset enumDataset = pWorkspaceMDB.get_Datasets(esriDatasetType.esriDTFeatureDataset);
- IFeatureDataset featureDs = enumDataset.Next() as IFeatureDataset;
- object[] obj = new object[2];
- while (featureDs != null)
- {
- IFeatureClass pFeatureClass;
- IFeatureClassContainer fcContainer = featureDs as IFeatureClassContainer;
- for (int i = 0; i < fcContainer.ClassCount; i++)
- {
- pFeatureClass = fcContainer.get_Class(i);
- obj[0] = CheckFields(pFeatureClass.Fields, pFeatureClass.AliasName);
- obj[1] = pFeatureClass.AliasName;
- dataGridViewX1.Rows.Add(obj);
- }
- featureDs = enumDataset.Next() as IFeatureDataset;
- }
- //2.遍历mdb的每一个独立要素类
- enumDataset = pWorkspaceMDB.get_Datasets(esriDatasetType.esriDTFeatureClass);
- IDataset dataset = enumDataset.Next();
- while (dataset != null)
- {
- IFeatureClass pFeatureClass = dataset as IFeatureClass;
- obj[0] = CheckFields(pFeatureClass.Fields, pFeatureClass.AliasName);
- obj[1] = pFeatureClass.AliasName;
- dataGridViewX1.Rows.Add(obj);
- dataset = enumDataset.Next();
- }
- //3.遍历mdb的每一个属性表
- enumDataset = pWorkspaceMDB.get_Datasets(esriDatasetType.esriDTTable);
- dataset = enumDataset.Next();
- while (dataset != null)
- {
- ITable pT = dataset as ITable;
- obj[0] = CheckFields(pT.Fields, dataset.Name);
- obj[1] = dataset.Name;
- dataGridViewX1.Rows.Add(obj);
- dataset = enumDataset.Next();
- }
- }
3.动态增加MDB文件到ComboBox,在打开检查字段的界面以前可以先添加需要检查的文件。
- /// <summary>
- /// 增加文件名到ComboBox中
- /// </summary>
- /// <param name="filename">文件名</param>
- public void AddDataToComboBox(string filename)
- {
- filenameComboBox.Items.Add(filename);
- }
4.查字段是否符合数据标准定义,所有数据结构都是预先定义好了的并且存在数据库中作为数据字典管理。
- /// <summary>
- /// 检查字段是否符合数据标准定义
- /// </summary>
- /// <param name="pSourceFileds">字段集</param>
- /// <param name="strTableName">对应的标准名</param>
- /// <returns>true:成功;false:失败</returns>
- private bool CheckFields(IFields pSourceFileds, string strTableName)
- {
- SqlHelper sh = new SqlHelper();
- //从数据库定义标准表中查找出字段的定义
- string sql = "select * from jcsjk_fielddefine where table_name ='"
- + strTableName.ToUpper() + "' or table_name='" + strTableName.ToLower() + "'";
- //如果字段数目不同肯定就不能通过检查了
- if (pSourceFileds.FieldCount != sh.GetRecordCount(sql))
- {
- return false;
- }
- bool result = true;
- OracleDataReader odr = sh.ReturnDataReader(sql);
- object[] obj1 = new object[4];
- object[] obj2 = new object[4];
- //分别检查字段名称,字段类型,字段长度和字段是否可以为空
- for (int i = 0; i < pSourceFileds.FieldCount; i++)
- {
- odr.Read();
- //根据标准中定义的名称查找检查的字段名称
- if (pSourceFileds.FindField(odr["NAME"].ToString()) >= 0)
- {
- IField pSourceField = pSourceFileds.get_Field(pSourceFileds.FindField(odr["NAME"].ToString()));
- obj1[0] = pSourceField.Name;
- obj1[1] = pSourceField.Type;
- obj1[2] = pSourceField.Length;
- obj1[3] = pSourceField.IsNullable;
- obj2[0] = odr["NAME"].ToString();
- if (odr["TYPE"].ToString() == "RowID")
- {
- obj2[1] = esriFieldType.esriFieldTypeOID;
- }
- else if (odr["type"].ToString() == "整数型")
- {
- obj2[1] = esriFieldType.esriFieldTypeInteger;
- }
- else if (odr["type"].ToString() == "浮点型")
- {
- obj2[1] = esriFieldType.esriFieldTypeDouble;
- }
- else if (odr["type"].ToString() == "字符型")
- {
- obj2[1] = esriFieldType.esriFieldTypeString;
- }
- else if (odr["type"].ToString() == "图元")
- {
- obj2[1] = esriFieldType.esriFieldTypeGeometry;
- }
- obj2[2] = odr["LENGTH"].ToString();
- if (odr["ISNULL"].ToString() == "是")
- {
- obj2[3] = true;
- }
- else
- {
- obj2[3] = false;
- }
- if (obj1[1].ToString() != obj2[1].ToString()
- || obj1[2].ToString() != obj2[2].ToString()
- || obj1[3].ToString() != obj2[3].ToString())
- {
- result = false;
- break;
- }
- }
- else
- {
- result = false;
- break;
- }
- }
- return result;
- }
5.点击一个具体的表名之后在另一个控件中显示这个表的字段的检查结果,主要显示这个是否成功,如果错误提示哪些方面的错误,例如字段数量不对(少了还是多了)、字段类型不对、数据的长度不匹配等。
- /// <summary>
- /// 点击一个具体的表名之后在另一个控件中显示这个表的字段的检查结果
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void dataGridViewX1_Click(object sender, EventArgs e)
- {
- if (dataGridViewX1.CurrentRow == null)
- {
- return;
- }
- string strTableName = dataGridViewX1.CurrentRow.Cells[1].Value.ToString();
- IWorkspaceFactory wf = new AccessWorkspaceFactory();
- IFeatureWorkspace pFeatureWorkspaceMDB = wf.OpenFromFile(filenameComboBox.SelectedItem.ToString(), 0) as IFeatureWorkspace;
- IWorkspace pWorkspaceMDB = pFeatureWorkspaceMDB as IWorkspace;
- //1.遍历mdb的每一个要素集
- IEnumDataset enumDataset = pWorkspaceMDB.get_Datasets(esriDatasetType.esriDTFeatureDataset);
- IFeatureDataset featureDs = enumDataset.Next() as IFeatureDataset;
- IFields pFs = null;
- while (featureDs != null)
- {
- IFeatureClass pFC = null;
- IFeatureClassContainer fcContainer = featureDs as IFeatureClassContainer;
- for (int i = 0; i < fcContainer.ClassCount; i++)
- {
- if (fcContainer.get_Class(i).AliasName.ToLower() == strTableName.ToLower())
- {
- pFC = fcContainer.get_Class(i);
- pFs = pFC.Fields;
- break;
- }
- }
- featureDs = enumDataset.Next() as IFeatureDataset;
- }
- //2.遍历mdb的每一个独立要素类
- if (pFs == null)
- {
- IFeatureClass pFC = null;
- enumDataset = pWorkspaceMDB.get_Datasets(esriDatasetType.esriDTFeatureClass);
- IDataset dataset = enumDataset.Next();
- while (dataset != null)
- {
- pFC = dataset as IFeatureClass;
- if (pFC.AliasName.ToLower() == strTableName.ToLower())
- {
- pFs = pFC.Fields;
- break;
- }
- dataset = enumDataset.Next();
- }
- }
- //3.遍历mdb的每一个属性表
- if (pFs == null)
- {
- ITable tc = null;
- enumDataset = pWorkspaceMDB.get_Datasets(esriDatasetType.esriDTTable);
- IDataset dataset = enumDataset.Next();
- while (dataset != null)
- {
- tc = dataset as ITable;
- if (dataset.Name.ToLower() == strTableName.ToLower())
- {
- pFs = tc.Fields;
- break;
- }
- dataset = enumDataset.Next();
- }
- }
- SqlHelper sh = new SqlHelper();
- string sql = "select * from jcsjk_fielddefine where table_name ='"
- + strTableName.ToUpper() + "' or table_name='" + strTableName.ToLower() + "'";
- if (sh.GetRecordCount(sql) <= 0)
- {
- errTxt.Text = "标准不存在,不能检查!";
- return;
- }
- if (pFs.FieldCount != sh.GetRecordCount(sql))
- {
- errTxt.Text = "标准检查未通过,字段数量不匹配!";
- return ;
- }
- OracleDataReader odr = sh.ReturnDataReader(sql);
- int count = 0;
- object[] obj = new object[2];
- for (int i = 0; i < pFs.FieldCount; i++)
- {
- odr.Read();
- //字段是否存在
- if (pFs.FindField(odr["NAME"].ToString()) >= 0)
- {
- IField pSourceField = pFs.get_Field(pFs.FindField(odr["NAME"].ToString()));
- //1.检查字段类型
- if (odr["TYPE"].ToString() == "RowID")
- {
- if (pSourceField.Type != esriFieldType.esriFieldTypeOID)
- {
- count++;
- obj[0] = pSourceField.AliasName;
- obj[1] = "字段类型错误";
- dataGridViewX2.Rows.Add(obj);
- continue;
- }
- }
- else if (odr["type"].ToString() == "整数型")
- {
- if (pSourceField.Type != esriFieldType.esriFieldTypeInteger)
- {
- count++;
- obj[0] = pSourceField.AliasName;
- obj[1] = "字段类型错误";
- dataGridViewX2.Rows.Add(obj);
- continue;
- }
- }
- else if (odr["type"].ToString() == "浮点型")
- {
- if (pSourceField.Type != esriFieldType.esriFieldTypeDouble)
- {
- count++;
- obj[0] = pSourceField.AliasName;
- obj[1] = "字段类型错误";
- dataGridViewX2.Rows.Add(obj);
- continue;
- }
- }
- else if (odr["type"].ToString() == "字符型")
- {
- if (pSourceField.Type != esriFieldType.esriFieldTypeString)
- {
- count++;
- obj[0] = pSourceField.AliasName;
- obj[1] = "字段类型错误";
- dataGridViewX2.Rows.Add(obj);
- continue;
- }
- }
- else if (odr["type"].ToString() == "图元")
- {
- if (pSourceField.Type != esriFieldType.esriFieldTypeGeometry)
- {
- count++;
- obj[0] = pSourceField.AliasName;
- obj[1] = "字段类型错误";
- dataGridViewX2.Rows.Add(obj);
- continue;
- }
- }
- //2.检查字段长度
- if (pSourceField.Length != int.Parse(odr["LENGTH"].ToString()))
- {
- count++;
- obj[0] = pSourceField.AliasName;
- obj[1] = "字段长度错误";
- dataGridViewX2.Rows.Add(obj);
- continue;
- }
- //3.检查字段是否为空
- if (odr["ISNULL"].ToString() == "是")
- {
- if (pSourceField.IsNullable != true)
- {
- count++;
- obj[0] = pSourceField.AliasName;
- obj[1] = "字段为空错误";
- dataGridViewX2.Rows.Add(obj);
- }
- }
- else
- {
- if (pSourceField.IsNullable != false)
- {
- count++;
- obj[0] = pSourceField.AliasName;
- obj[1] = "字段为空错误";
- dataGridViewX2.Rows.Add(obj);
- }
- }
- }
- else
- {
- errTxt.Text = "标准检查未通过,没有找到标准里面的" + odr["NAME"].ToString() + "字段!";
- return;
- }
- }
- if (count > 0)
- {
- errTxt.Text = "标准检查未通过,失败字段数:" + count.ToString();
- }
- else
- {
- errTxt.Text = "标准检查通过!";
- }
- }
6.总结:本篇只介绍了一个功能就是检查对应的空间数据结构是否匹配,这是导入数据到数据库中的必备步骤,不然可能造成数据库的损坏,也浪费了一些不必要的操作。本篇的代码中还有datagridView和combobox等控件的使用,例如怎样在datagridview控件的固定单元增加值等。