基于ArcGIS10.0和Oracle10g的空间数据管理平台十六(C#开发)-空间数据编辑(上)

来源:互联网 发布:人工智能各个方面英文 编辑:程序博客网 时间:2024/05/20 10:54

今天要介绍的内容比较高级,就是通过可视化的操作进行空间数据的编辑操作。不过这里面涉及到很多难度比较大的高级功能,例如怎样选中一个图元、怎样移动图元、怎样确认图元的位置以及实现编辑的撤销操作等等。下面按照自己实现的步骤详细介绍如下。

1.定义空间数据编辑类的成员变量,具体代码如下:

[csharp] view plaincopy
  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.初始相关成员变量和数据

[csharp] view plaincopy
  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. }  


    上面代码首先由地图控件来获取它的一个实例对象,然后得到地图控件中的地图对象,接着就调用函数载入图层并设置相应操作按钮的初始化状态。载入图层的代码实现 如下:

[csharp] view plaincopy
  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. }  


    设置操作按钮的代码如下:

[csharp] view plaincopy
  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. }  

 

    也有禁止相应按钮功能的函数代码如下:

[csharp] view plaincopy
  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.实现加载图层到图层控件中去,这样就可以在图形控件中进行编辑操作了,具体加载代码如下:

[csharp] view plaincopy
  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。

[csharp] view plaincopy
  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.开始编辑,使工作空间处于可编辑状态,在进行图层编辑前必须调用本方法。

[csharp] view plaincopy
  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.删除当前图层中选中的地图对象

[csharp] view plaincopy
  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.撤消以前所做的编辑

[csharp] view plaincopy
  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.停止编辑,并将以前的编辑结果保存到数据文件中。

[csharp] view plaincopy
  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.取得选中的地图对象集合
[csharp] view plaincopy
  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(nullfalseout pCursor);  
  25.     return (IFeatureCursor)pCursor;  
  26. }  
10.取得当前图层所在的工作空间
[csharp] view plaincopy
  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.向图层中添加新的地图对象,并使之处于选中状态。
[csharp] view plaincopy
  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. }  

    由于这一部分内容太多,剩余的实现功能和内容将在下一篇博客中继续向下介绍其详细的代码实现。
原创粉丝点击