基于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 }
3.实现加载图层到图层控件中去,这样就可以在图形控件中进行编辑操作了,具体加载代码如下:
 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 }
4.检查工作空间中是否有数据处于编辑状态,是就返回true。
 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 }
5.开始编辑,使工作空间处于可编辑状态,在进行图层编辑前必须调用本方法。
 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 }
6.删除当前图层中选中的地图对象
 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 }
7.撤消以前所做的编辑
 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 }
8.停止编辑,并将以前的编辑结果保存到数据文件中。
 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.取得当前图层所在的工作空间
 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 }
11.向图层中添加新的地图对象,并使之处于选中状态。
 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 }
    由于这一部分内容太多,剩余的实现功能和内容将在下一篇博客中继续向下介绍其详细的代码实现。
posted @ 2012-02-14 01:19  蔷薇理想人生  阅读(2136)  评论(1编辑  收藏  举报