基于ArcGIS10.0和Oracle10g的空間數據管理平臺十六(C#開發)-空間數據編輯(上)
我的新浪微博:http://weibo.com/freshairbrucewoo。
歡迎大家相互交流,共同提高技術。
今天要介紹的內容比較高級,就是通過可視化的操作進行空間數據的編輯操作。不過這里面涉及到很多難度比較大的高級功能,例如怎樣選中一個圖元、怎樣移動圖元、怎樣確認圖元的位置以及實現編輯的撤銷操作等等。下面按照自己實現的步驟詳細介紹如下。
1.定義空間數據編輯類的成員變量,具體代碼如下:
1 private IFeatureWorkspace pFW;
2 private IMapControl3 m_MapControl; //地圖控件
3 private IMap m_pMap; //地圖控件中的地圖
4 private ILayer m_pCurrentLayer; //地圖中的當前操作圖層
5 private IFeature m_pEditFeature; //當前編輯的要素
6 private IPoint m_pPoint; //當前鼠標點擊位置
7 private IDisplayFeedback m_pFeedback; //用于地圖顯示
8 private IPointCollection m_pPointCollection; //當前要素的點集
9 private bool m_bInUse; //是否處于同一個編輯狀態
10 private bool m_bEditingFtr; //是否為編輯要素狀態
11 private bool m_bSketching; //是否為新建要素狀態
12 private bool m_bSelecting; //是否為選擇要素狀態
13 private bool m_bMove; //是否為移動要素狀態
2.初始相關成員變量和數據
1 private void FrmSpatialDataEdit_Load(object sender, EventArgs e)
2 {
3 // Setup the application
4 m_MapControl = (IMapControl3)axMapControl1.GetOcx(); //獲取地圖控件
5 m_pMap = m_MapControl.Map;
6 cboTasks.SelectedIndex = 0;
7 LoadLayers(); //載入圖層
8 SetControlStates(); //設置四個命令按鈕狀態
9 }
1 /// <summary>
2 /// 載入圖層,并在地圖空間中加入第一個圖層
3 /// </summary>
4 private void LoadLayers()
5 {
6 //1.遍歷SDE的每一個獨立要素集中的要素類
7 IWorkspace pW = MapOperation.GetFeatrueWorkspace() as IWorkspace;
8 IEnumDataset pED = pW.get_Datasets(esriDatasetType.esriDTFeatureDataset);
9 IFeatureDataset pFD = pED.Next() as IFeatureDataset;
10
11 while (pFD != null)
12 {
13 IFeatureClass pFC;
14 IFeatureClassContainer pFCC = pFD as IFeatureClassContainer;
15 for (int i = 0; i < pFCC.ClassCount; i++)
16 {
17 pFC = pFCC.get_Class(i);
18 cboLayers.Items.Add(pFC.AliasName);
19 }
20
21 pFD = pED.Next() as IFeatureDataset;
22 }
23
24 //2.遍歷SDE的每一個獨立要素類
25 pED = pW.get_Datasets(esriDatasetType.esriDTFeatureClass);
26 IDataset pD = pED.Next();
27 while (pD != null)
28 {
29 IFeatureClass pFC = pD as IFeatureClass;
30
31 cboLayers.Items.Add(pFC.AliasName);
32 pD = pED.Next();
33 }
34
35 cboLayers.SelectedIndex = 0;
36 AddLayerToMapCtl(cboLayers.SelectedItem.ToString(), true);
37 }
1 /// <summary>
2 /// 設置四個命令按鍵的功能
3 /// </summary>
4 private void SetControlStates()
5 {
6 bool bEnabled = InEdit();
7
8 btnStartEditing.Enabled = !bEnabled;
9 btnDelete.Enabled = bEnabled;
10 btnUndo.Enabled = bEnabled;
11 btnStopEditing.Enabled = bEnabled;
12 cboTasks.Enabled = bEnabled;
13
14 if (bEnabled)
15 {
16 lblTask.ForeColor = Color.Black;
17 }
18 else
19 {
20 lblTask.ForeColor = Color.Gray;
21 }
22 }
1 private void DisableControls()
2 {
3 // Disables all but the layer selection combo
4 btnStartEditing.Enabled = false;
5 btnDelete.Enabled = false;
6 btnUndo.Enabled = false;
7 btnStopEditing.Enabled = false;
8 lblTask.ForeColor = Color.Gray;
9 }
1 /// <summary>
2 /// 加入圖層到地圖空間中
3 /// </summary>
4 /// <param name="layerName">圖層名稱</param>
5 /// <param name="isVisible">是否顯示</param>
6 private void AddLayerToMapCtl(string layerName, bool isVisible)
7 {
8 if (pFW == null)
9 {
10 pFW = MapOperation.GetFeatrueWorkspace();
11 }
12 IFeatureClass pFC;
13 try
14 {
15 pFC = pFW.OpenFeatureClass(layerName);
16 }
17 catch (Exception)
18 {
19 return;
20 }
21
22 IFeatureLayer pFL = new FeatureLayerClass();
23 pFL.FeatureClass = pFC;
24 pFL.Name = layerName;
25 pFL.Visible = isVisible;
26
27 axMapControl1.Map.AddLayer(pFL);
28 axMapControl1.ActiveView.Refresh();
29 }
1 /// <summary>
2 /// 檢查工作空間中是否有數據處于編輯狀態
3 /// </summary>
4 /// <returns>是否正在編輯</returns>
5 private bool InEdit()
6 {
7 // Check edit conditions before allowing edit to stop
8 if (m_pCurrentLayer == null)
9 {
10 return false;
11 }
12 IFeatureLayer pFeatureLayer = (IFeatureLayer)m_pCurrentLayer;
13
14 if (pFeatureLayer.FeatureClass == null)
15 {
16 return false;
17 }
18 IDataset pDataset = (IDataset)pFeatureLayer.FeatureClass;
19 if (pDataset == null)
20 {
21 return false;
22 }
23 IWorkspaceEdit pWorkspaceEdit = (IWorkspaceEdit)pDataset.Workspace;
24 if (pWorkspaceEdit.IsBeingEdited())
25 {
26 return true;
27 }
28 return false;
29 }
1 /// <summary>
2 /// 開始編輯,使工作空間處于可編輯狀態
3 /// 在進行圖層編輯前必須調用本方法
4 /// </summary>
5 private void StartEditing()
6 {
7 // Check edit conditions before allowing edit to start
8 if (m_pCurrentLayer == null)
9 {
10 return;
11 }
12 if ((IGeoFeatureLayer)m_pCurrentLayer == null)
13 {
14 return;
15 }
16 IFeatureLayer pFeatureLayer = (IFeatureLayer)m_pCurrentLayer;
17 IDataset pDataset = (IDataset)pFeatureLayer.FeatureClass;
18 if (pDataset == null)
19 {
20 return;
21 }
22
23 // Start editing, making sure that undo/redo are enabled
24 // 開始編輯,并設置Undo/Redo 為可用
25 IWorkspaceEdit pWorkspaceEdit = (IWorkspaceEdit)pDataset.Workspace;
26 if (!pWorkspaceEdit.IsBeingEdited())
27 {
28 pWorkspaceEdit.StartEditing(true);
29 pWorkspaceEdit.EnableUndoRedo();
30 LogHelp.writeUpdateDataLog(cboLayers.SelectedItem.ToString(), "1", "update");
31 }
32 }
1 /// <summary>
2 /// 刪除當前圖層中選中的地圖對象
3 /// </summary>
4 private void DeleteSelectedFeatures()
5 {
6 if (m_pCurrentLayer == null)
7 {
8 return;
9 }
10
11 // If there are no features currently selected then nothing to do
12 IFeatureCursor pFeatureCursor = GetSelectedFeatures();
13 if (pFeatureCursor == null)
14 {
15 return;
16 }
17
18 // Loop over the selected features deleting each in turn
19 IWorkspaceEdit pWorkspaceEdit = GetWorkspaceEdit();
20 pWorkspaceEdit.StartEditOperation();
21 IFeature pFeature = pFeatureCursor.NextFeature();
22 while (pFeature != null)
23 {
24 pFeature.Delete();
25 pFeature = pFeatureCursor.NextFeature();
26 }
27 pWorkspaceEdit.StopEditOperation();
28
29 IActiveView pActiveView = (IActiveView)m_pMap;
30 pActiveView.Refresh();
31 }
1 /// <summary>
2 /// 撤消以前所做的編輯
3 /// </summary>
4 private void UndoEdit()
5 {
6 // Check that editing is possible
7 if (m_pCurrentLayer == null)
8 {
9 return;
10 }
11 IFeatureLayer pFeatureLayer = (IFeatureLayer)m_pCurrentLayer;
12 IDataset pDataset = (IDataset)pFeatureLayer.FeatureClass;
13 if (pDataset == null)
14 {
15 return;
16 }
17
18 /// If edits have taken place then roll-back the last one
19 IWorkspaceEdit pWorkspaceEdit = (IWorkspaceEdit)pDataset.Workspace;
20 bool bHasUndos = false;
21 pWorkspaceEdit.HasUndos(ref bHasUndos);
22 if (bHasUndos)
23 {
24 pWorkspaceEdit.UndoEditOperation();
25 }
26
27 IActiveView pActiveView = (IActiveView)m_pMap;
28 pActiveView.Refresh();
29 }
1 /// <summary>
2 /// 停止編輯,并將以前的編輯結果保存到數據文件中。
3 /// </summary>
4 private void StopEditing()
5 {
6 // Check edit conditions before allowing edit to stop
7 if (m_pCurrentLayer == null)
8 {
9 return;
10 }
11 IFeatureLayer pFeatureLayer = (IFeatureLayer)m_pCurrentLayer;
12 if (pFeatureLayer.FeatureClass == null)
13 {
14 return;
15 }
16 IDataset pDataset = (IDataset)pFeatureLayer.FeatureClass;
17 if (pDataset == null)
18 {
19 return;
20 }
21
22 // If the current document has been edited then prompt the user to save changes
23 //如果數據已被修改,則提示用戶是否保存
24 IWorkspaceEdit pWorkspaceEdit = (IWorkspaceEdit)pDataset.Workspace;
25 if (pWorkspaceEdit.IsBeingEdited())
26 {
27 bool bHasEdits = false;
28 pWorkspaceEdit.HasEdits(ref bHasEdits);
29 bool bSave = false;
30 if (bHasEdits)
31 {
32 DialogResult result;
33 result = MessageBox.Show(this, "是否保存已做的修改?", "提示",
34 MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
35 if (DialogResult.Yes == result)
36 {
37 bSave = true;
38 }
39 }
40 pWorkspaceEdit.StopEditing(bSave);
41 }
42
43 m_pMap.ClearSelection();
44 IActiveView pActiveView = (IActiveView)m_pMap;
45 pActiveView.Refresh();
46 }
9.取得選中的地圖對象集合
1 /// <summary>
2 /// 取得選中的地圖對象集合
3 /// </summary>
4 /// <returns>地圖對象游標</returns>
5 private IFeatureCursor GetSelectedFeatures()
6 {
7 if (m_pCurrentLayer == null)
8 {
9 return null;
10 }
11
12 // If there are no features selected let the user know
13 IFeatureSelection pFeatSel = (IFeatureSelection)m_pCurrentLayer;
14 ISelectionSet pSelectionSet = pFeatSel.SelectionSet;
15 if (pSelectionSet.Count == 0)
16 {
17 MessageBox.Show("No features are selected in the '" + m_pCurrentLayer.Name + "' layer", "Error",
18 MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
19 return null;
20 }
21
22 // Otherwise get all of the features back from the selection
23 ICursor pCursor;
24 pSelectionSet.Search(null, false, out pCursor);
25 return (IFeatureCursor)pCursor;
26 }
10.取得當前圖層所在的工作空間
11.向圖層中添加新的地圖對象,并使之處于選中狀態。
由于這一部分內容太多,剩余的實現功能和內容將在下一篇博客中繼續向下介紹其詳細的代碼實現。
1 /// <summary>
2 /// 取得當前圖層所在的工作空間
3 /// </summary>
4 /// <returns>工作空間</returns>
5 private IWorkspaceEdit GetWorkspaceEdit()
6 {
7 if (m_pCurrentLayer == null)
8 {
9 return null;
10 }
11
12 IFeatureLayer pFeatureLayer = (IFeatureLayer)m_pCurrentLayer;
13 IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;
14 IDataset pDataset = (IDataset)pFeatureClass;
15 if (pDataset == null)
16 {
17 return null;
18 }
19 return (IWorkspaceEdit)pDataset.Workspace;
20 }
1 /// <summary>
2 /// 向圖層中添加新的地圖對象,并使之處于選中狀態
3 /// </summary>
4 /// <param name="pGeom">圖形對象</param>
5 private void CreateFeature(IGeometry pGeom)
6 {
7 if (pGeom == null)
8 {
9 return;
10 }
11 if (m_pCurrentLayer == null)
12 {
13 return;
14 }
15
16 // Create the feature
17 IWorkspaceEdit pWorkspaceEdit = GetWorkspaceEdit();
18 IFeatureLayer pFeatureLayer = (IFeatureLayer)m_pCurrentLayer;
19 IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;
20 pWorkspaceEdit.StartEditOperation();
21 IFeature pFeature = pFeatureClass.CreateFeature();
22 pFeature.Shape = pGeom;
23 pFeature.Store();
24 pWorkspaceEdit.StopEditOperation();
25
26 // Refresh the relevant area of the active view
27 IActiveView pActiveView = (IActiveView)m_pMap;
28 if (pGeom.GeometryType == esriGeometryType.esriGeometryPoint)
29 {
30 double length;
31 length = ConvertPixelsToMapUnits(pActiveView, 30);
32 ITopologicalOperator pTopo = (ITopologicalOperator)pGeom;
33 IGeometry pBuffer = pTopo.Buffer(length);
34 pActiveView.PartialRefresh((esriViewDrawPhase)(esriDrawPhase.esriDPGeography | esriDrawPhase.esriDPSelection), m_pCurrentLayer, pBuffer.Envelope);
35 }
36 else
37 {
38 pActiveView.PartialRefresh((esriViewDrawPhase)(esriDrawPhase.esriDPGeography | esriDrawPhase.esriDPSelection), m_pCurrentLayer, pGeom.Envelope);
39 }
40 }
浙公網安備 33010602011771號