基于ArcGIS10.0和Oracle10g的空間數據管理平臺九(C#開發)-空間數據導入RDBMS上-Shape格式
先打一個廣告:我的獨立博客網址是:http://it_blog.jd-app.com/。
我的新浪微博:http://weibo.com/freshairbrucewoo。
歡迎大家相互交流,共同提高技術。
這一篇博文終于要真正接觸操作空間數據了,今天要完成講解的功能就是導入Shape格式和MDB的空間數據格式到基于ArcSDE空間數據庫插件的Oracle10g數據庫中。這里面涉及到的功能和操作非常的多,我準備用兩篇文章來介紹,這一篇介紹導入前的準備工作和Shape格式的導入。對于空間數據和ArcGIS沒有基礎知識的可以先了解和學習一下這方面的知識,在我這個項目系列博文中也有一些這方面的基礎知識介紹,可以看看!下面開始具體介紹這個過程。
1.選擇導入的格式
當然這里只支持兩種格式(Shape和MDB),當然可以支持更多的空間數據格式,我在一篇博文專門介紹了八種數據格式的空間數據。為什么需要各種空間數據格式的導入呢?因為空間數據的來源多種多樣,具體來源可以到google搜索。為了統一管理各種格式或各種來源的空間數據格式,也為了從集中的空間數據中發現更大的商業信息,所以必須找一種統一的格式來管理,我這個項目當然就是采用的基于空間數據庫插件的Oracle10g,采用這種方式主要是想借用RDBMS的強大功能。
實現選擇格式的思路相當的簡單,就是用一個界面采用單選按鈕來選擇,具體實現選擇的功能如下:
/// <summary>
/// 下一步,選擇導入空間數據的格式,支持Shape和MDB格式
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void nextBtn_Click(object sender, EventArgs e)
{
this.Close();
if (radioButton1.Checked)
{
//導入為Shape空間數據格式
FrmImportShapeFile faif = new FrmImportShapeFile();
faif.ShowDialog();
}
else
{
//導入為MDB空間數據格式
FrmImportMDBFile fim = new FrmImportMDBFile();
fim.ShowDialog();
}
}
從代碼可以看出我們可以通過選擇會進入下一個具體導入的界面,下一個界面的功能就是很復雜了。主要復雜的功能是對于需要導入的空間數據格式的檢查,包括完整性檢查、與數據庫中已有表結構的數據結構是否一一對應或者能夠兼容----如字段個數、字段類型、字段長度等。
2.Shape空間數據格式的導入
2.1 變量定義與初始化(在構造函數中初始化,也可以在對話框的Load函數中),見如下代碼:
private IFeatureWorkspace pFW;//工作空間
public int sc_id = 4326;//空間參考系的ID
private bool bSelectField = false;
private Dictionary<string, IFields> fieldDic;//用于保存需要檢查各個字段
public FrmImportShapeFile()
{
InitializeComponent();
if (pFW == null)
{
pFW = MapOperation.GetFeatrueWorkspace();
}
fieldDic = new Dictionary<string, IFields>();
}
2.2 回到上一步:選擇導入格式界面
/// <summary>
/// 回到上一步:就是選擇導入空間數據選擇界面
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void preBtn_Click(object sender, EventArgs e)
{
FrmSelectFileFormat fsff = new FrmSelectFileFormat();
fsff.index = 0;
fsff.Show();
this.Close();
}
2.3 使能相應按鈕功能的復選按鈕功能
/// <summary>
/// 根據復選按鈕使能相應的其他功能按鈕
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)//使能選擇字段
{
bSelectField = true;
selectUploadFieldBtn.Enabled = true;
checkUploadFieldBtn.Enabled = true;
}
else
{
bSelectField = false;
selectUploadFieldBtn.Enabled = false;
checkUploadFieldBtn.Enabled = false;
}
}
2.4 轉換導入Shape文件數據到SDE數據庫中
/// <summary>
/// 轉換導入Shape文件數據到SDE數據庫中
/// </summary>
/// <param name="strPath">Shape文件路徑</param>
/// <param name="strFile">Shape文件名稱,到后綴名的</param>
/// <param name="strTableName">導入到SDE中的表名稱</param>
private void ConvertShpToSDE(string strPath, string strFile, string strTableName)
{
//創建一個輸出shp文件的工作空間
IWorkspaceFactory pShpWorkspaceFactory = new ShapefileWorkspaceFactoryClass();
IWorkspace pSourceWS = pShpWorkspaceFactory.OpenFromFile(strPath, 0);
/*
//1.遍歷數據集中的要素類并導入
IEnumDataset enumDs = pSourceWS.get_Datasets(esriDatasetType.esriDTFeatureDataset);
IFeatureDataset featureDs = enumDs.Next() as IFeatureDataset;
while (featureDs != null)
{
IFeatureClass featClass;
IFeatureClassContainer fcContainer = featureDs as IFeatureClassContainer;
for (int i = 0; i < fcContainer.ClassCount; i++)
{
featClass = fcContainer.get_Class(i);
if (MapOperation.FindClassByName(workspace as IWorkspace,
null, featClass.AliasName) != null)
{
MapOperation.AddFeatureClassToSDE(pSourceWS as IWorkspace,
workspace as IWorkspace, featClass.AliasName, featClass.AliasName);
}
else
{
MapOperation.ConvertFeatureClass(pSourceWS as IWorkspace,
workspace as IWorkspace, featClass.AliasName, featClass.AliasName);
}
}
featureDs = enumDs.Next() as IFeatureDataset;
}
//2.遍歷游離的要素類并導入
enumDs = pSourceWS.get_Datasets(esriDatasetType.esriDTFeatureClass);
IFeatureClass featCl = enumDs.Next() as IFeatureClass;
while (featCl != null)
{
if (MapOperation.FindClassByName(workspace as IWorkspace,
null, featCl.AliasName) != null)
{
MapOperation.AddFeatureClassToSDE(pSourceWS as IWorkspace,
workspace as IWorkspace, featCl.AliasName, featCl.AliasName);
}
else
{
MapOperation.ConvertFeatureClass(pSourceWS as IWorkspace,
workspace as IWorkspace, featCl.AliasName, featCl.AliasName);
}
featCl = enumDs.Next() as IFeatureClass;
}*/
IFeatureWorkspace pSourceFWS = (IFeatureWorkspace)pSourceWS;
SqlHelper sh = new SqlHelper();
IFeatureClass pFC = pSourceFWS.OpenFeatureClass(strFile);
IWorkspace2 pW2 = pFW as IWorkspace2;
string sql = string.Empty;
//判斷是否在SDE中已經存在要素類,存在就追加,否則新建
if (pW2.get_NameExists(esriDatasetType.esriDTFeatureClass, strTableName))
{
//是否選擇了上載字段
if (fieldDic.ContainsKey(strFile))
{
//選擇了上載字段,就將對應字段插入到要素類中
AddFeatureClassToSDE(pSourceFWS, pFW, strFile, strTableName);
}
else
{
//沒有就將全部字段插入要素類中
MapOperation.AddFeatureClassToSDE(pSourceWS, pFW as IWorkspace, pFC.AliasName, strTableName);
}
}
else
{
//新建導入,在數據字典中插入一條游離圖層的記錄
MapOperation.ConvertFeatureClass(pSourceWS as IWorkspace, pFW as IWorkspace,
pFC.AliasName, strTableName, sc_id);
//MapOperation.CreateFeatureClass(pFW as IWorkspace2, null, strTableName, pFC.Fields, null, null, "");
//MapOperation.AddFeatureClassToSDE(pSourceWS, pFW as IWorkspace, pFC.AliasName, strTableName);
sql = "select * from layer where table_name='" + strTableName + "'";
if (sh.GetRecordCount(sql) > 0)
{
return;
}
sql = "select max(ID) from layer";
OracleDataReader odr = sh.ReturnDataReader(sql);
int result = 0;
if (odr.Read())
{
result = int.Parse(odr[0].ToString());
result += 1;
}
Hashtable ht = new Hashtable();
ht.Add("ID", result);
sql = "select id from element where name='游離圖層'";
odr = sh.ReturnDataReader(sql);
if (odr.Read())
{
ht.Add("PID", int.Parse(odr[0].ToString()));
}
else
{
ht.Add("PID", 2025);
}
ht.Add("TABLE_NAME", strTableName);
ht.Add("TABLE_MAPNAME", strTableName);
ht.Add("DESCRIPTION", "無輔助信息!");
if (pFC.ShapeType == esriGeometryType.esriGeometryPoint
|| pFC.ShapeType == esriGeometryType.esriGeometryMultipoint)
{
ht.Add("TYPE", "PT");
}
else if (pFC.ShapeType == esriGeometryType.esriGeometryLine
|| pFC.ShapeType == esriGeometryType.esriGeometryPolyline)
{
ht.Add("TYPE", "PL");
}
else if (pFC.ShapeType == esriGeometryType.esriGeometryPolygon)
{
ht.Add("TYPE", "PY");
}
else
{
ht.Add("TYPE", "PY");
}
sh.Insert("layer", ht);
}
}
上面的代碼比較復雜,其中涉及到一個功能就是是否選擇一些字段追加到以后的數據庫表中,如果不是就全部導入,否則就是執行部分導入功能,全部導入功能是在前面介紹的空間數據操作類((1)MapOperation.AddFeatureClassToSDE(pSourceWS, pFW as IWorkspace, pFC.AliasName, strTableName);追加功能。(2)MapOperation.ConvertFeatureClass(pSourceWS as IWorkspace, pFW as IWorkspace, pFC.AliasName, strTableName, sc_id);新建一個表導入)介紹實現的,就不在具體介紹了,下面介紹部分追求字段功能,如下:
1 ///<summary>
2 /// 將Shape文件中要素類選擇的字段轉換追加到sde數據庫已有的要素類中
3 ///</summary>
4 ///<param name="pSourceFW">源要素工作空間</param>
5 ///<param name="pTargetFW">目標要素工作空間</param>
6 ///<param name="nameOfSourceFeatureClass">源要素類名稱</param>
7 ///<param name="nameOfTargetFeatureClass">目標要素類名稱</param>
8 public void AddFeatureClassToSDE(IFeatureWorkspace pSourceFW, IFeatureWorkspace pTargetFW,
9 string nameOfSourceFeatureClass, string nameOfTargetFeatureClass)
10 {
11 //打開源要素類
12 IFeatureClass pSourceFC = pSourceFW.OpenFeatureClass(nameOfSourceFeatureClass);
13 //打開目標要素類
14 IFeatureClass pTargetFC = pTargetFW.OpenFeatureClass(nameOfTargetFeatureClass);
15 //遍歷源要素類的要素并依次插入目標要素類
16 IFeatureCursor pFeaCursor = pSourceFC.Search(null, false);
17 IFeature pFeature = pFeaCursor.NextFeature();
18
19 IField pField = new FieldClass();
20 int iIndex = 0;
21
22 while (pFeature != null)
23 {
24 IFeature tempFeature = pTargetFC.CreateFeature();
25 tempFeature.Shape = pFeature.Shape;
26
27 try
28 {
29 //添加字段值
30 IFields pFs = fieldDic[nameOfSourceFeatureClass];
31 for (int j = 0; j < pFs.FieldCount; j++)
32 {
33 pField = pFs.get_Field(j);
34 iIndex = tempFeature.Fields.FindField(pField.Name);
35 if (pField.Editable && iIndex != -1)
36 {
37 tempFeature.set_Value(iIndex, pFeature.get_Value(j));
38 }
39 }
40 tempFeature.Store();
41 }
42 catch (System.Exception ex)
43 {
44 MessageBox.Show(ex.Message);
45 return;
46 }
47 pFeature = pFeaCursor.NextFeature();
48 }
49 }
2.5 導入要素類到某一個具體的工作空間
1 ///<summary>
2 /// 導入要素類到工作空間
3 ///</summary>
4 ///<param name="apFD"></param>
5 ///<param name="pathName"></param>
6 ///<param name="fileName"></param>
7 private void ImportFeatureClassToWorkSpace(IFeatureDataset apFD, string pathName, string fileName)
8 {
9 IWorkspaceName pInWorkspaceName;
10 IFeatureDatasetName pOutFeatureDSName;
11 IFeatureClassName pInFeatureClassName;
12 IDatasetName pInDatasetName;
13 IFeatureClassName pOutFeatureClassName;
14 IDatasetName pOutDatasetName;
15 long iCounter;
16 IFields pOutFields, pInFields;
17 IFieldChecker pFieldChecker;
18 IField pGeoField;
19 IGeometryDef pOutGeometryDef;
20 IGeometryDefEdit pOutGeometryDefEdit;
21 IName pName;
22 IFeatureClass pInFeatureClass;
23 IFeatureDataConverter pShpToClsConverter;
24 IEnumFieldError pEnumFieldError = null;
25
26 //得到一個輸入SHP文件的工作空間,
27 pInWorkspaceName = new WorkspaceNameClass();
28 pInWorkspaceName.PathName = pathName;
29 pInWorkspaceName.WorkspaceFactoryProgID = "esriCore.ShapefileWorkspaceFactory.1";
30 //創建一個新的要素類名稱,目的是為了以來PNAME接口的OPEN方法打開SHP文件
31 pInFeatureClassName = new FeatureClassNameClass();
32 pInDatasetName = (IDatasetName)pInFeatureClassName;
33 pInDatasetName.Name = fileName;
34 pInDatasetName.WorkspaceName = pInWorkspaceName;
35 //打開一個SHP文件,將要讀取它的字段集合
36 pName = (IName)pInFeatureClassName;
37 pInFeatureClass = (IFeatureClass)pName.Open();
38 //通過FIELDCHECKER檢查字段的合法性,為輸入要素類獲得字段集合
39 pInFields = pInFeatureClass.Fields;
40 pFieldChecker = new FieldChecker();
41 pFieldChecker.Validate(pInFields, out pEnumFieldError, out pOutFields);
42 //通過循環查找幾何字段
43 pGeoField = null;
44 for (iCounter = 0; iCounter < pOutFields.FieldCount; iCounter++)
45 {
46 if (pOutFields.get_Field((int)iCounter).Type == esriFieldType.esriFieldTypeGeometry)
47 {
48 pGeoField = pOutFields.get_Field((int)iCounter);
49 break;
50 }
51 }
52 //得到幾何字段的幾何定義
53 pOutGeometryDef = pGeoField.GeometryDef;
54 //設置幾何字段的空間參考和網格
55 pOutGeometryDefEdit = (IGeometryDefEdit)pOutGeometryDef;
56 pOutGeometryDefEdit.GridCount_2 = 1;
57 pOutGeometryDefEdit.set_GridSize(0, 1500000);
58
59 //創建一個新的要素類名稱作為可用的參數
60 pOutFeatureClassName = new FeatureClassNameClass();
61 pOutDatasetName = (IDatasetName)pOutFeatureClassName;
62 pOutDatasetName.Name = pInDatasetName.Name;
63
64 //創建一個新的數據集名稱作為可用的參數
65 pOutFeatureDSName = (IFeatureDatasetName)new FeatureDatasetName();
66 //因為ConvertFeatureClass需要傳入一個IFeatureDatasetName的參數,
67 //通過它確定導入生成的要素類的工作空間和要素集合
68 //情況一
69 //如果本函數的參數(IFeatureDataset)是一個確切的值,
70 //那么將它轉換成IFeatureDatasetName接口就可以了。因為ConvertFeatureClass根據該接口就
71 //可以確定工作空間和要素集合,IFeatureClassName就可以不考慮上述問題
72 //情況二
73 //如果本函數的參數(IFeatureDataset)是一個NULL值,表示要創建獨立要素類,
74 //那么ConvertFeatureClass函數無法根據IFeatureDatasetName參數確定工作空間和要素集合
75 //這個時候需要IFeatureClassName參數確定工作空間和要素集合
76
77 //如果參數的值是NULL,說明要創建獨立要素類
78 if (apFD == null)
79 {
80 //創建一個不存在的要素集合pFDN,通過它將IFeatureClassName和工作空間連接起來,
81 //而ConvertFeatureClass函數并不使用該變量作為參數,
82 IFeatureDatasetName pFDN = new FeatureDatasetNameClass();
83 IDatasetName pDN = (IDatasetName)pFDN;
84 IDataset pDS = (IDataset)pFW;
85 pDN.WorkspaceName = (IWorkspaceName)pDS.FullName;
86 pDN.Name = pDS.Name;
87 pOutFeatureClassName.FeatureDatasetName = (IDatasetName)pFDN;
88 //將pOutFeatureDSName設置為Null,將它做為參數給ConvertFeatureClass函數,
89 //因為IFeatureClassName本身已經和工作空間關聯了,生成的
90 //要素類在工作空間的根目錄下,即獨立要素類
91 pOutFeatureDSName = null;
92
93 }
94 else//創建的要素類是在給定的參數(要素集合)下
95 {
96 pOutFeatureDSName = (IFeatureDatasetName)apFD.FullName;
97 }
98
99 //開始導入
100 pShpToClsConverter = new FeatureDataConverterClass();
101 pShpToClsConverter.ConvertFeatureClass(pInFeatureClassName, null, pOutFeatureDSName,
102 pOutFeatureClassName, pOutGeometryDef, pOutFields, "", 1000, 0);
103 }
2.6 添加一個Shape文件到需要導入的空間列表中(包括具體的信息,以供查看和選擇):
1 ///<summary>
2 /// 添加一個Shape文件到DataGridViewX1中
3 ///</summary>
4 ///<param name="sender"></param>
5 ///<param name="e"></param>
6 private void addFileBtn_Click(object sender, EventArgs e)
7 {
8 OpenFileDialog ofd = new OpenFileDialog();
9
10 //打開SHP文件
11 string StrFilter = "SHP文件(.shp) | *.shp";
12 ofd.Filter = StrFilter;
13 string ImportShapeFileName;
14 if (ofd.ShowDialog() == DialogResult.OK)
15 {
16 ImportShapeFileName = ofd.FileName;
17 }
18 else
19 {
20 return;
21 }
22
23 string ImportFileName = System.IO.Path.GetFileName(ImportShapeFileName);
24 string ImportFileShortName = System.IO.Path.GetFileNameWithoutExtension(ImportShapeFileName);
25 string ImportFilePath = System.IO.Path.GetDirectoryName(ImportShapeFileName);
26 //導入Shape文件的相關信息到空間中
27 object[] obj = new object[3];
28 obj[0] = ImportFileName;
29 obj[1] = ImportFileShortName;
30 obj[2] = ImportFilePath;
31 dataGridViewX1.Rows.Add(obj);
32 }
2.7 和上一個功能類型,不過這個是添加一個目錄,即這目錄下的所有Shape文件都會被添加到控件列表中。
1 ///<summary>
2 /// 添加一個目錄下的所有Shape文件到DataGridViewX1中
3 ///</summary>
4 ///<param name="sender"></param>
5 ///<param name="e"></param>
6 private void addFolderBtn_Click(object sender, EventArgs e)
7 {
8 FolderBrowserDialog folder = new FolderBrowserDialog();
9 if (folder.ShowDialog() == DialogResult.OK)
10 {
11 string strPath = folder.SelectedPath;
12 if (strPath == "")
13 {
14 return ;
15 }
16
17 string []fileNames = Directory.GetFiles(strPath);
18 string strTemp;
19 foreach (string str in fileNames)
20 {
21 strTemp = str.Remove(0, str.LastIndexOf('\\')+1);
22 if (strTemp.Substring(strTemp.IndexOf('.')) == ".shp")
23 {
24 object[] obj = new object[3];
25
26 obj[0] = strTemp;
27 strTemp = strTemp.Remove(strTemp.IndexOf('.'));
28 obj[1] = strTemp;
29 obj[2] = strPath;
30 dataGridViewX1.Rows.Add(obj);
31 }
32 }
33 }
34 }
2.8從顯示Shape文件信息的控件列表中刪除一個Shape文件的信息,就不需要導入的Shape文件可以先刪除,免得影響視線。
1 ///<summary>
2 /// 從DataGridViewX1刪除一個文件
3 ///</summary>
4 ///<param name="sender"></param>
5 ///<param name="e"></param>
6 private void delFileBtn_Click(object sender, EventArgs e)
7 {
8
9 if (dataGridViewX1.CurrentRow.Index >= 0)
10 {
11 dataGridViewX1.Rows.Remove(dataGridViewX1.CurrentRow);
12 }
13 else
14 {
15 MessageBox.Show("請選擇一個要刪除的行!");
16 return ;
17 }
18 }
2.9完成導入Shape文件的按鈕功能
1 ///<summary>
2 /// 完成導入的功能,當所有準備和檢查功能已經做完并且通過就可以通過完成按鈕完成導入了
3 ///</summary>
4 ///<param name="sender"></param>
5 ///<param name="e"></param>
6 private void finishBtn_Click(object sender, EventArgs e)
7 {
8 int fileCount = dataGridViewX1.Rows.Count;
9 //多個Shape文件內容依次導入
10 for (int i = 0; i < fileCount; ++i)
11 {
12 // string str = dataGridViewX1.Rows[i].Cells[1].Value.ToString();
13 // ImportFeatureClassToWorkSpace(null,dataGridViewX1.Rows[i].Cells[2].Value.ToString(), str);
14 ConvertShpToSDE(dataGridViewX1.Rows[i].Cells[2].Value.ToString(),
15 dataGridViewX1.Rows[i].Cells[0].Value.ToString(),
16 dataGridViewX1.Rows[i].Cells[1].Value.ToString());
17 }
18 LogHelp.writeLog(FrmMain.username, "空間數據管理", "空間數據Shape格式轉換導入成功");
19 MessageBox.Show("導入數據完成!");
20 Close();
21 }
真正的導入函數是前面已經介紹過的ConvertShpToSDE函數。
2.10 把控件中的Shape文件信息保存起來(配置文件)以便下一次直接導入這些文件。
1 ///<summary>
2 /// 保存DataGridViewX1的文件列表到配置文件中
3 ///</summary>
4 ///<param name="sender"></param>
5 ///<param name="e"></param>
6 private void saveSetBtn_Click(object sender, EventArgs e)
7 {
8 System.IO.FileStream fs = new System.IO.FileStream(Directory.GetCurrentDirectory()+"\\set.ini", FileMode.Create);
9 StreamWriter sw = new StreamWriter(fs);
10
11 int fileCount = dataGridViewX1.Rows.Count - 1;
12 //開始寫入
13 for (int i = 0; i < fileCount; ++i)
14 {
15 string str = dataGridViewX1.Rows[i].Cells[0].Value.ToString();
16 sw.WriteLine(str);
17 str = dataGridViewX1.Rows[i].Cells[1].Value.ToString();
18 sw.WriteLine(str);
19 str = dataGridViewX1.Rows[i].Cells[2].Value.ToString();
20 sw.WriteLine(str);
21 }
22 //清空緩沖區
23 sw.Flush();
24 //關閉流
25 sw.Close();
26 fs.Close();
27 }
2.11讀取配置文件的文件列表加載到控件中
1 ///<summary>
2 /// 讀取配置文件的文件列表加載到DataGridViewX1中
3 ///</summary>
4 ///<param name="sender"></param>
5 ///<param name="e"></param>
6 private void readSetBtn_Click(object sender, EventArgs e)
7 {
8 dataGridViewX1.Rows.Clear();
9
10 StreamReader objReader = new StreamReader(Directory.GetCurrentDirectory() + "\\set.ini");
11 string sLine = "";
12 while ((sLine = objReader.ReadLine()) != null)
13 {
14 object[] obj = new object[3];
15 obj[0] = sLine;
16 obj[1] = objReader.ReadLine();
17 obj[2] = objReader.ReadLine();
18
19 dataGridViewX1.Rows.Add(obj);
20 }
21 objReader.Close();
22 }
2.12 選擇空間參考系(空間數據都有的)
1 ///<summary>
2 /// 選擇空間參考系
3 ///</summary>
4 ///<param name="sender"></param>
5 ///<param name="e"></param>
6 private void selectBtn_Click(object sender, EventArgs e)
7 {
8 FrmSelectSpatialReference fssr = new FrmSelectSpatialReference();
9 fssr.ShowDialog();
10 if (fssr.bOk)
11 {
12 spatialReTxt.Text = fssr.sc_id.ToString();
13 sc_id = fssr.sc_id;
14 }
15 }
2.13選擇上載字段(沒有選擇的將不會導入到數據庫中)
1 ///<summary>
2 /// 選擇上載字段
3 ///</summary>
4 ///<param name="sender"></param>
5 ///<param name="e"></param>
6 private void selectUploadFieldBtn_Click(object sender, EventArgs e)
7 {
8 if (dataGridViewX1.CurrentRow == null)
9 {
10 MessageBox.Show("選擇一行!");
11 return;
12 }
13 string strPath = dataGridViewX1.CurrentRow.Cells[2].Value.ToString();
14 string strName = dataGridViewX1.CurrentRow.Cells[0].Value.ToString();
15
16 FrmSelectField fsf = new FrmSelectField();
17 fsf.InitDataGridView();
18 //創建一個輸出shp文件的工作空間
19 IWorkspaceFactory pShpWorkspaceFactory = new ShapefileWorkspaceFactoryClass();
20 IWorkspace pSourceWS = pShpWorkspaceFactory.OpenFromFile(strPath, 0);
21 IFeatureWorkspace pSourceFWS = (IFeatureWorkspace)pSourceWS;
22 IFeatureClass pFC = pSourceFWS.OpenFeatureClass(strName);
23 object[] obj = new object[4];
24 for (int i = 0; i < pFC.Fields.FieldCount; i++)
25 {
26 IField field = pFC.Fields.get_Field(i);
27 obj[0] = false;
28 obj[1] = field.Name;
29 obj[2] = field.Type;
30 obj[3] = field.Length;
31 fsf.AddRowToDataGridView(obj);
32 }
33 fsf.ShowDialog();
34 //確實確定了選擇,就把選擇的結果和文件名對應保存起來。
35 if (fsf.bSelect)
36 {
37 IFields pFds = new FieldsClass();
38 IFieldsEdit pFdsEdit = pFds as IFieldsEdit;
39 for (int i = 0; i < pFC.Fields.FieldCount; i++)
40 {
41 if (fsf.RowsIsSelect(i))
42 {
43 IField field = pFC.Fields.get_Field(i);
44 pFdsEdit.AddField(field);
45 }
46 }
47 if (fieldDic.ContainsKey(strName))
48 {
49 fieldDic.Remove(strName);
50 }
51 fieldDic.Add(strName, pFds);
52 }
53 }
2.14檢查導入字段是否滿足要求,不滿足就提示哪些不滿足,滿足以后才能執行導入功能。
1 ///<summary>
2 /// 檢查字段按鈕功能,檢查需要導入字段是否滿足要求
3 ///</summary>
4 ///<param name="sender"></param>
5 ///<param name="e"></param>
6 private void checkUploadFieldBtn_Click(object sender, EventArgs e)
7 {
8 if (dataGridViewX1.CurrentRow == null)
9 {
10 MessageBox.Show("選擇一行!");
11 return;
12 }
13
14 string strPath = dataGridViewX1.CurrentRow.Cells[2].Value.ToString();
15 string strTableName = dataGridViewX1.CurrentRow.Cells[1].Value.ToString();
16 string strName = dataGridViewX1.CurrentRow.Cells[0].Value.ToString();
17 /*
18 IWorkspace2 pW = pFW as IWorkspace2;
19 if (!pW.get_NameExists(esriDatasetType.esriDTFeatureClass, strTableName))
20 {
21 MessageBox.Show("數據庫中不存在此表結構,不能檢查!");
22 return;
23 }
24
25 //1.遍歷數據集中的要素類找到并打開目標要素類
26
27 IEnumDataset enumDs = (pFW as IWorkspace).get_Datasets(esriDatasetType.esriDTFeatureDataset);
28 IFeatureDataset featureDs = enumDs.Next() as IFeatureDataset;
29 IFeatureClass pSDEFC = null;
30 while (featureDs != null)
31 {
32 IFeatureClassContainer fcContainer = featureDs as IFeatureClassContainer;
33 for (int i = 0; i < fcContainer.ClassCount; i++)
34 {
35 IFeatureClass pTempFC = fcContainer.get_Class(i);
36 string strTemp = pTempFC.AliasName;
37 if (pTempFC.AliasName.IndexOf('.') >= 0)
38 {
39 strTemp = strTemp.Substring(strTemp.IndexOf('.')+1);
40 }
41
42 if (strTemp.ToUpper() == strTableName.ToUpper())
43 {
44 pSDEFC = fcContainer.get_Class(i);
45 break;
46 }
47 }
48 if (pSDEFC != null)
49 {
50 break;
51 }
52 featureDs = enumDs.Next() as IFeatureDataset;
53 }
54
55 //2.遍歷游離的要素類
56 if (pSDEFC == null)
57 {
58 enumDs = (pFW as IWorkspace).get_Datasets(esriDatasetType.esriDTFeatureClass);
59 IFeatureClass pTempFC = enumDs.Next() as IFeatureClass;
60 while (pTempFC != null)
61 {
62 string strTemp = pTempFC.AliasName;
63 if (pTempFC.AliasName.IndexOf('.') >= 0)
64 {
65 strTemp = strTemp.Substring(strTemp.IndexOf('.')+1);
66 }
67
68 if (strTemp.ToUpper() == strTableName.ToUpper())
69 {
70 pSDEFC = pTempFC;
71 break;
72 }
73 pTempFC = enumDs.Next() as IFeatureClass;
74 }
75 }
76 */
77 SqlHelper sh = new SqlHelper();
78 string sql = "select * from jcsjk_fielddefine where table_name='" + strTableName.ToLower() + "'";
79 if (sh.GetRecordCount(sql) <= 0)
80 {
81 MessageBox.Show("沒有定義該數據標準,不能檢查!");
82 return;
83 }
84
85 if (!fieldDic.ContainsKey(strName))
86 {
87 if (MessageBox.Show("此文件還沒有選擇上載字段,默認全部上載!是否繼續檢查?", "提示信息",
88 MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
89 {
90 IWorkspaceFactory pShpWorkspaceFactory = new ShapefileWorkspaceFactoryClass();
91 IWorkspace pSourceWS = pShpWorkspaceFactory.OpenFromFile(strPath, 0);
92 IFeatureWorkspace pSourceFWS = (IFeatureWorkspace)pSourceWS;
93 IFeatureClass pFC = pSourceFWS.OpenFeatureClass(strName);
94
95 if (CheckFields(pFC.Fields, strTableName))
96 {
97 MessageBox.Show("字段匹配");
98 }
99 else
100 {
101 MessageBox.Show("字段不匹配");
102 }
103 }
104 }
105 else
106 {
107 if (CheckFields(fieldDic[strName], strTableName))
108 {
109 MessageBox.Show("字段匹配");
110 }
111 else
112 {
113 MessageBox.Show("字段不匹配");
114 }
115 }
116 }
117
118 ///<summary>
119 /// 檢查字段是否符合數據標準定義
120 ///</summary>
121 ///<param name="pSourceFileds">字段集</param>
122 ///<param name="strTableName">對應的標準名</param>
123 ///<returns></returns>
124 private bool CheckFields(IFields pSourceFileds, string strTableName)
125 {
126 SqlHelper sh = new SqlHelper();
127 string sql = "select * from jcsjk_fielddefine where table_name ='"
128 + strTableName.ToUpper() + "' or table_name='" + strTableName.ToLower() + "'";
129
130 if (pSourceFileds.FieldCount != sh.GetRecordCount(sql))
131 {
132 MessageBox.Show("字段數量不匹配!");
133 return false;
134 }
135 bool result = true;
136 FrmFieldCheckResult ffcr = new FrmFieldCheckResult();
137 ffcr.InitDataGridView1();
138 ffcr.InitDataGridView2();
139 OracleDataReader odr = sh.ReturnDataReader(sql);
140 object[] obj1 = new object[5];
141 object[] obj2 = new object[4];
142 for (int i = 0; i < pSourceFileds.FieldCount; i++)
143 {
144 odr.Read();
145 bool bMatch = true;
146 if (odr["TYPE"].ToString() == "RowID")
147 {
148 IField pSourceField = pSourceFileds.get_Field(pSourceFileds.FindField("FID"));
149
150 obj1[0] = pSourceField.Name;
151 obj1[1] = pSourceField.Type;
152 obj1[2] = pSourceField.Length;
153 obj1[3] = pSourceField.IsNullable;
154
155 obj2[0] = odr["NAME"].ToString();
156 obj2[1] = esriFieldType.esriFieldTypeOID;
157 obj2[2] = odr["LENGTH"].ToString();
158 if (odr["ISNULL"].ToString() == "是")
159 {
160 obj2[3] = true;
161 }
162 else
163 {
164 obj2[3] = false;
165 }
166
167 if (obj1[1].ToString() != obj2[1].ToString()
168 || obj1[2].ToString() != obj2[2].ToString()
169 || obj1[3].ToString() != obj2[3].ToString())
170 {
171 bMatch = false;
172 result = false;
173 }
174 obj1[4] = bMatch;
175 ffcr.AddRowToDataGridView1(obj1);
176 ffcr.AddRowToDataGridView2(obj2);
177 }
178 else if (pSourceFileds.FindField(odr["NAME"].ToString()) >= 0)
179 {
180 IField pSourceField = pSourceFileds.get_Field(pSourceFileds.FindField(odr["NAME"].ToString()));
181
182 obj1[0] = pSourceField.Name;
183 obj1[1] = pSourceField.Type;
184 obj1[2] = pSourceField.Length;
185 obj1[3] = pSourceField.IsNullable;
186
187 obj2[0] = odr["NAME"].ToString();
188 if (odr["TYPE"].ToString() == "RowID")
189 {
190 obj2[1] = esriFieldType.esriFieldTypeOID;
191 }
192 else if (odr["type"].ToString() == "整數型")
193 {
194 obj2[1] = esriFieldType.esriFieldTypeInteger;
195 }
196 else if (odr["type"].ToString() == "浮點型")
197 {
198 obj2[1] = esriFieldType.esriFieldTypeDouble;
199 }
200 else if (odr["type"].ToString() == "字符型")
201 {
202 obj2[1] = esriFieldType.esriFieldTypeString;
203 }
204 else if (odr["type"].ToString() == "圖元")
205 {
206 obj2[1] = esriFieldType.esriFieldTypeGeometry;
207 }
208 obj2[2] = odr["LENGTH"].ToString();
209 if (odr["ISNULL"].ToString() == "是")
210 {
211 obj2[3] = true;
212 }
213 else
214 {
215 obj2[3] = false;
216 }
217
218 if (obj1[1].ToString() != obj2[1].ToString()
219 || obj1[2].ToString() != obj2[2].ToString()
220 || obj1[3].ToString() != obj2[3].ToString())
221 {
222 bMatch = false;
223 result = false;
224 }
225 obj1[4] = bMatch;
226 ffcr.AddRowToDataGridView1(obj1);
227 ffcr.AddRowToDataGridView2(obj2);
228 }
229 else
230 {
231 MessageBox.Show("字段名稱不匹配!");
232 result = false;
233 }
234 }
235 ffcr.ShowDialog();
236 return result;
237 }
2.15根據已有的Shape文件,打開檢查字段界面,選中一個具體的Shape文件就檢查一個Shape文件,通過的就在控件中標示出來。
1 ///<summary>
2 /// 檢查文件字段,字段類型和長度
3 ///</summary>
4 ///<param name="sender"></param>
5 ///<param name="e"></param>
6 private void checkFileFieldBtn_Click(object sender, EventArgs e)
7 {
8 if (dataGridViewX1.CurrentRow == null)
9 {
10 MessageBox.Show("選擇一行!");
11 return;
12 }
13 string strPath = dataGridViewX1.CurrentRow.Cells[2].Value.ToString();
14 string strName = dataGridViewX1.CurrentRow.Cells[0].Value.ToString();
15
16 FrmSelectField fsf = new FrmSelectField();
17 fsf.SetBtnVisible(false);
18 fsf.Text = ((ButtonX)sender).Text;
19 fsf.InitDataGridView();
20 //創建一個輸出shp文件的工作空間
21 IWorkspaceFactory pShpWorkspaceFactory = new ShapefileWorkspaceFactoryClass();
22 IWorkspace pSourceWS = pShpWorkspaceFactory.OpenFromFile(strPath, 0);
23 IFeatureWorkspace pSourceFWS = (IFeatureWorkspace)pSourceWS;
24 IFeatureClass pFC = pSourceFWS.OpenFeatureClass(strName);
25 object[] obj = new object[4];
26 for (int i = 0; i < pFC.Fields.FieldCount; i++)
27 {
28 IField field = pFC.Fields.get_Field(i);
29 obj[0] = false;
30 obj[1] = field.Name;
31 obj[2] = field.Type;
32 obj[3] = field.Length;
33 fsf.AddRowToDataGridView(obj);
34 }
35 fsf.SetDataGridViewColumn(0);
36 fsf.ShowDialog();
37 }
3.總結
空間數據的轉換是比較復雜和繁瑣的功能,需要考慮的方面非常多,只有細心的一點一滴的做好每一步才能出色的完成這些功能,尤其是數據格式的檢查是最復雜的,必須一個一個字段去對比。
今天到此為止!
浙公網安備 33010602011771號