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

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

上一篇介绍了空间数据编辑一部分实现,今天继续完成剩余的部分实现。

1.根据选择编辑任务的不同显示不同形状的鼠标,以便指示相应任务方便编辑操作

[csharp] view plaincopy
  1.  1         /// <summary>  
  2.  2 /// 根据选择编辑任务的不同显示不同形状的鼠标,以便指示相应任务方便编辑操作  
  3.  3 /// </summary>  
  4.  4 /// <param name="sender"></param>  
  5.  5 /// <param name="e"></param>  
  6.  6         private void cboTasks_SelectedIndexChanged(object sender, EventArgs e)  
  7.  7         {  
  8.  8             // Restate   
  9.  9             m_MapControl.MousePointer = esriControlsMousePointer.esriPointerDefault;  
  10. 10             m_bEditingFtr = false;  
  11. 11             m_bSketching = false;  
  12.   
  13. 12             m_bSelecting = false;  
  14. 13             m_bMove = false;  
  15. 14   
  16. 15             // Select an operation and mouse pointer depending on the user choice   
  17. 16             switch (cboTasks.SelectedIndex)  
  18. 17             {  
  19. 18                 case 0:  
  20. 19                     // Do Nothing - the tool has already been reset   
  21. 20                     break;  
  22. 21                 case 1:  
  23. 22                     m_MapControl.MousePointer = esriControlsMousePointer.esriPointerCrosshair;  
  24. 23                     m_bEditingFtr = true;  
  25. 24                     break;  
  26. 25                 case 2:  
  27. 26                     m_MapControl.MousePointer = esriControlsMousePointer.esriPointerPencil;  
  28. 27                     m_bSketching = true;  
  29. 28                     break;  
  30. 29                 case 3:  
  31. 30                     m_MapControl.MousePointer = esriControlsMousePointer.esriPointerCrosshair;  
  32. 31                     m_bSelecting = true;  
  33. 32                     break;  
  34. 33                 case 4:  
  35. 34                     m_MapControl.MousePointer = esriControlsMousePointer.esriPointerHand;  
  36. 35                     m_bMove = true;  
  37. 36                     break;  
  38. 37             }   
  39. 38   
  40. 39         }  

2.选择需要的图层并且在地图编辑控件中显示出来

[csharp] view plaincopy
  1. 1         /// <summary>  
  2.  2 /// 选择需要的图层并且在地图编辑控件中显示出来  
  3.  3 /// </summary>  
  4.  4 /// <param name="sender"></param>  
  5.  5 /// <param name="e"></param>  
  6.  6         private void cboLayers_SelectedIndexChanged(object sender, EventArgs e)  
  7.  7         {  
  8.  8             if (m_pMap == null)  
  9.  9             {  
  10. 10                 return;  
  11. 11             }  
  12. 12   
  13. 13             // Clear any existing selection   
  14. 14             m_pMap.ClearSelection();  
  15. 15             IActiveView ipActiveView;  
  16. 16             ipActiveView = (IActiveView)m_pMap;  
  17. 17             ipActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, nullnull);  
  18. 18   
  19. 19             String strLayerName = cboLayers.SelectedItem.ToString();  
  20. 20             axMapControl1.Map.ClearLayers();  
  21. 21             AddLayerToMapCtl(strLayerName, true);  
  22. 22             m_pCurrentLayer = m_pMap.get_Layer(0);  
  23. 23   
  24. 24             SetControlStates();  
  25. 25         }  

3.测试是否击中地图对象或地图对象上的节点

 
[csharp] view plaincopy
  1. 1         /// <summary>  
  2.  2 /// 测试是否击中地图对象或地图对象上的节点  
  3.  3 /// </summary>  
  4.  4 /// <param name="tolerance">查询容差</param>  
  5.  5 /// <param name="pPoint">点击位置</param>  
  6.  6 /// <param name="pFeature">测试对象</param>  
  7.  7 /// <param name="pHitPoint">查询目标点</param>  
  8.  8 /// <param name="hitDist">目标点与点击点距离</param>  
  9.  9 /// <param name="partIndex">节索引</param>  
  10. 10 /// <param name="vertexIndex">点索引</param>  
  11. 11 /// <param name="vertexHit">是否击中点</param>  
  12. 12 /// <returns>是否击中测试对象</returns>  
  13. 13         private bool TestGeometryHit(double tolerance, IPoint pPoint, IFeature pFeature,   
  14. 14             ref IPoint pHitPoint, ref double hitDist, ref int partIndex, ref int vertexIndex,   
  15. 15             ref int vertexOffset, ref bool vertexHit)  
  16. 16         {  
  17. 17             // Function returns true if a feature's shape is hit and further defines   
  18. 18 // if a vertex lies within the tolorance   
  19. 19             bool bRetVal = false;  
  20. 20             IGeometry pGeom = (IGeometry)pFeature.Shape;  
  21. 21   
  22. 22             IHitTest pHitTest = (IHitTest)pGeom;  
  23. 23             pHitPoint = new ESRI.ArcGIS.Geometry.Point();  
  24. 24             bool bTrue = true;  
  25. 25             // First check if a vertex was hit   
  26. 26 // 检查节点是否被击中  
  27. 27             if (pHitTest.HitTest(pPoint, tolerance, esriGeometryHitPartType.esriGeometryPartVertex,   
  28. 28                 pHitPoint, ref hitDist, ref partIndex, ref vertexIndex, ref bTrue))  
  29. 29             {  
  30. 30                 bRetVal = true;  
  31. 31                 vertexHit = true;  
  32. 32             }  
  33. 33             // Secondly check if a boundary was hit   
  34. 34 // 检边界是否被击中  
  35. 35             else if (pHitTest.HitTest(pPoint, tolerance,  esriGeometryHitPartType.esriGeometryPartBoundary,  
  36. 36                 pHitPoint, ref hitDist, ref partIndex, ref vertexIndex, ref bTrue))  
  37. 37             {  
  38. 38                 bRetVal = true;  
  39. 39                 vertexHit = false;  
  40. 40             }  
  41. 41   
  42. 42             // Calculate offset to vertexIndex for multipatch geometries   
  43. 43             if (partIndex > 0)  
  44. 44             {  
  45. 45                 IGeometryCollection pGeomColn = (IGeometryCollection)pGeom;  
  46. 46                 vertexOffset = 0;  
  47. 47                 for (int i = 0; i < partIndex; i++)  
  48. 48                 {  
  49. 49                     IPointCollection pPointColn = (IPointCollection)pGeomColn.get_Geometry(i);  
  50. 50                     vertexOffset = vertexOffset + pPointColn.PointCount;  
  51. 51                 }  
  52. 52             }  
  53. 53   
  54. 54             return bRetVal;  
  55. 55         }  

4.向图层中更新新的地图对象,并使之处于选中状态

 
[csharp] view plaincopy
  1. 1         /// <summary>  
  2.  2 /// 向图层中更新新的地图对象,并使之处于选中状态  
  3.  3 /// </summary>  
  4.  4 /// <param name="pFeature"></param>  
  5.  5 /// <param name="pGeometry"></param>  
  6.  6         private void UpdateFeature(IFeature pFeature, IGeometry pGeometry)  
  7.  7         {  
  8.  8             // Make sure we are actually editing this layer. If not give a warning.   
  9.  9             IDataset pDataset = (IDataset)pFeature.Class;  
  10. 10             IWorkspaceEdit pWorkspaceEdit = (IWorkspaceEdit)pDataset.Workspace;  
  11. 11             if (!pWorkspaceEdit.IsBeingEdited())  
  12. 12             {  
  13. 13                 System.Windows.Forms.MessageBox.Show("This feature is in a layer not in edit mode. \nEdit cannot be made.Start edit and try again.",  
  14. 14                     "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);  
  15. 15             }  
  16. 16   
  17. 17             // If all tests succeed allow feature edits to be saved   
  18. 18             pWorkspaceEdit.StartEditOperation();  
  19. 19             pFeature.Shape = pGeometry;  
  20. 20             pFeature.Store();  
  21. 21             pWorkspaceEdit.StopEditOperation();  
  22. 22         }  

5.屏幕坐标转换为地图坐标

[csharp] view plaincopy
  1.  1         /// <summary>  
  2.  2 /// 屏幕坐标转换为地图坐标  
  3.  3 /// </summary>  
  4.  4 /// <param name="pActiveView">地图</param>  
  5.  5 /// <param name="pixelUnits">屏幕坐标</param>  
  6.  6 /// <returns>地图坐标</returns>  
  7.  7         private double ConvertPixelsToMapUnits(IActiveView pActiveView, double pixelUnits)  
  8.  8         {  
  9.  9             // Uses the ratio of the size of the map in pixels to map units to do the conversion   
  10. 10             IPoint p1 = pActiveView.ScreenDisplay.DisplayTransformation.VisibleBounds.UpperLeft;  
  11. 11             IPoint p2 = pActiveView.ScreenDisplay.DisplayTransformation.VisibleBounds.UpperRight;  
  12. 12             int x1, x2, y1, y2;  
  13. 13             pActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(p1, out x1, out y1);  
  14. 14             pActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(p2, out x2, out y2);  
  15. 15             double pixelExtent = x2 - x1;  
  16. 16             double realWorldDisplayExtent = pActiveView.ScreenDisplay.DisplayTransformation.VisibleBounds.Width;  
  17. 17             double sizeOfOnePixel = realWorldDisplayExtent / pixelExtent;  
  18. 18             return pixelUnits * sizeOfOnePixel;  
  19. 19         }  

6.处理地图控件上的目标按下事件

 
[csharp] view plaincopy
  1. 1         private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)  
  2.  2         {  
  3.  3             //首先判断当前用户选择了何种任务,并去完成相应的任务;如果没有选择任何任务,  
  4.  4 //即cboTasks的选项为没有任务时,该事件处理程序用于放大、缩小地图,鼠标左键  
  5.  5 //用于放大,其他键用于缩小  
  6.  6             m_pMap.ClearSelection();//清除地图中已选的要素  
  7.  7               
  8.  8             if (m_bSketching)  
  9.  9             {  
  10. 10                 //新建要素任务处理  
  11. 11                 SketchMouseDown(e.x, e.y);  
  12. 12             }  
  13. 13             else if (m_bSelecting)  
  14. 14             {  
  15. 15                 //选择要素任务处理  
  16. 16                 SelectMouseDown(e.x, e.y);  
  17. 17             }  
  18. 18             else if (m_bEditingFtr)  
  19. 19             {  
  20. 20                 //编辑要素任务处理  
  21. 21                 EditFeature(e.x, e.y);  
  22. 22             }  
  23. 23             else if (m_bMove)  
  24. 24             {  
  25. 25                 //移动要素  
  26. 26                 MoveFeatureMouseDown(e.x, e.y);  
  27. 27             }  
  28. 28             else  
  29. 29             {  
  30. 30                 // Zoom in/out depending on which button was pressed   
  31. 31                 IActiveView pActiveView = (IActiveView)m_pMap;  
  32. 32                 IEnvelope pEnvelope = pActiveView.Extent;  
  33. 33                 ESRI.ArcGIS.Geometry.Point pnt = new ESRI.ArcGIS.Geometry.Point();  
  34. 34                 IPoint iPnt = pnt;  
  35. 35                 iPnt.X = e.mapX;  
  36. 36                 iPnt.Y = e.mapY;  
  37. 37                 pEnvelope.CenterAt(iPnt);  
  38. 38                 if (e.button == 1) // left button   
  39. 39                 {  
  40. 40                     //放大视图  
  41. 41                     pEnvelope.Expand(0.5, 0.5, true);  
  42. 42                 }  
  43. 43                 else  
  44. 44                 {  
  45. 45                     //缩小视图  
  46. 46                     pEnvelope.Expand(2, 2, true);  
  47. 47                 }  
  48. 48                 pActiveView.Extent = pEnvelope;  
  49. 49                 pActiveView.Refresh();  
  50. 50             }   
  51. 51   
  52. 52         }  

7.处理地图控件上的鼠标移动事件

[csharp] view plaincopy
  1.  1         private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)  
  2.  2         {  
  3.  3             if (m_bSketching)  
  4.  4             {  
  5.  5                 //新建要素任务处理  
  6.  6                 SketchMouseMove(e.x, e.y);  
  7.  7             }  
  8.  8             else if (m_bEditingFtr)  
  9.  9             {  
  10. 10                 //编辑要素任务处理  
  11. 11                 FtrEditMouseMove(e.x, e.y);  
  12. 12             }  
  13. 13             else if (m_bMove)  
  14. 14             {  
  15. 15                 //移动要素任务处理  
  16. 16                 MoveFeatureMouseMove(e.x, e.y);  
  17. 17             }  
  18. 18   
  19. 19         }  

8.处理地图控件上的鼠标按下事件

[csharp] view plaincopy
  1.  1         private void axMapControl1_OnMouseUp(object sender, IMapControlEvents2_OnMouseUpEvent e)  
  2.  2         {  
  3.  3             if (m_bEditingFtr)  
  4.  4             {  
  5.  5                 //结束编辑任务  
  6.  6                 EndFtrEdit(e.x, e.y);  
  7.  7             }  
  8.  8             else if (m_bMove)  
  9.  9             {  
  10. 10                 //结束移动要素任务  
  11. 11                 MoveFeatureEnd();  
  12. 12             }  
  13. 13   
  14. 14         }  

9.新建对象方法:当前图层为点图层时,每调用一次就新点一个点对象,当前图层为线图层或面图层时,第一次调用开始新建对象,并添加当前点,以后每调用一次,即向新对象中添加一个点,调用NewFeatureEnd方法完成对象创建 。

 
[csharp] view plaincopy
  1. 1         /// <summary>  
  2.  2 /// 新建对象方法  
  3.  3 /// 当前图层为点图层时,每调用一次就新点一个点对象  
  4.  4 /// 当前图层为线图层或面图层时,第一次调用开始新建对象,并添加当前点,  
  5.  5 /// 以后每调用一次,即向新对象中添加一个点,调用NewFeatureEnd方法完成对象创建  
  6.  6 /// 在Map.MouseDown事件中调用本方法  
  7.  7 /// </summary>  
  8.  8 /// <param name="x">鼠标X坐标,屏幕坐标</param>  
  9.  9 /// <param name="y">鼠标Y坐标,屏幕坐标</param>  
  10. 10         private void SketchMouseDown(int x, int y)  
  11. 11         {  
  12. 12             // Starts a new sketch or adds a point to an existing one, of a type   
  13. 13 // determined by the current layer selected in the layers combo.   
  14. 14   
  15. 15 // Can only sketch on GeoFeature layers   
  16. 16             if (m_pCurrentLayer == null)  
  17. 17             {  
  18. 18                 return;  
  19. 19             }  
  20. 20             if ((IGeoFeatureLayer)m_pCurrentLayer == null)  
  21. 21             {  
  22. 22                 return;  
  23. 23             }  
  24. 24   
  25. 25             // Get the mouse down point in map coordinates   
  26. 26             IFeatureLayer pFeatureLayer = (IFeatureLayer)m_pCurrentLayer;  
  27. 27             if (pFeatureLayer.FeatureClass == null)  
  28. 28             {  
  29. 29                 return;  
  30. 30             }  
  31. 31             IActiveView pActiveView = (IActiveView)m_pMap;  
  32. 32             IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);  
  33. 33   
  34. 34             // if (this is a fresh sketch) create an appropriate feedback object,   
  35. 35 // otherwise extent the existing feedback   
  36. 36 // 如果是新开始创建的对象,则相应的创建一个新的Feedback对象;  
  37. 37 // 否则,向已存在的Feedback对象中加点  
  38. 38             if (!m_bInUse)  
  39. 39             {  
  40. 40                 m_pMap.ClearSelection();  //清除地图选中对象  
  41. 41                 switch (pFeatureLayer.FeatureClass.ShapeType)  
  42. 42                 {  
  43. 43                     case esriGeometryType.esriGeometryPoint:  
  44. 44                         CreateFeature(pPoint);  
  45. 45                         break;  
  46. 46                     case esriGeometryType.esriGeometryMultipoint:  
  47. 47                         m_bInUse = true;  
  48. 48                         m_pFeedback = new NewMultiPointFeedback();  
  49. 49                         INewMultiPointFeedback pMPFeed = (INewMultiPointFeedback)m_pFeedback;  
  50. 50                         m_pPointCollection = new Multipoint();  
  51. 51                         pMPFeed.Start(m_pPointCollection, pPoint);  
  52. 52                         break;  
  53. 53                     case esriGeometryType.esriGeometryPolyline:  
  54. 54                         m_bInUse = true;  
  55. 55                         m_pFeedback = new NewLineFeedback();  
  56. 56                         INewLineFeedback pLineFeed = (INewLineFeedback)m_pFeedback;  
  57. 57                         pLineFeed.Start(pPoint);  
  58. 58                         break;  
  59. 59                     case esriGeometryType.esriGeometryPolygon:  
  60. 60                         m_bInUse = true;  
  61. 61                         m_pFeedback = new NewPolygonFeedback();  
  62. 62                         INewPolygonFeedback pPolyFeed = (INewPolygonFeedback)m_pFeedback;  
  63. 63                         pPolyFeed.Start(pPoint);  
  64. 64                         break;  
  65. 65                 }  
  66. 66                 if (m_pFeedback != null)  
  67. 67                 {  
  68. 68                     m_pFeedback.Display = pActiveView.ScreenDisplay;  
  69. 69                 }  
  70. 70             }  
  71. 71             else  
  72. 72             {  
  73. 73                 if (m_pFeedback is INewMultiPointFeedback)  
  74. 74                 {  
  75. 75                     object Missing = Type.Missing;  
  76. 76                     m_pPointCollection.AddPoint(pPoint, ref Missing, ref Missing);  
  77. 77                 }  
  78. 78                 else if (m_pFeedback is INewLineFeedback)  
  79. 79                 {  
  80. 80                     INewLineFeedback pLineFeed = (INewLineFeedback)m_pFeedback;  
  81. 81                     pLineFeed.AddPoint(pPoint);  
  82. 82                 }  
  83. 83                 else if (m_pFeedback is INewPolygonFeedback)  
  84. 84                 {  
  85. 85                     INewPolygonFeedback pPolyFeed = (INewPolygonFeedback)m_pFeedback;  
  86. 86                     pPolyFeed.AddPoint(pPoint);  
  87. 87                 }  
  88. 88             }  
  89. 89         }  

10.新建对象过程中鼠标移动方法,产生Track效果,在Map.MouseMove事件中调用本方法

[csharp] view plaincopy
  1.  1         /// <summary>  
  2.  2 /// 新建对象过程中鼠标移动方法,产生Track效果  
  3.  3 /// 在Map.MouseMove事件中调用本方法  
  4.  4 /// </summary>  
  5.  5 /// <param name="x">鼠标X坐标,屏幕坐标</param>  
  6.  6 /// <param name="y">鼠标Y坐标,屏幕坐标</param>  
  7.  7         private void SketchMouseMove(int x, int y)  
  8.  8         {  
  9.  9             if (!m_bInUse || m_pFeedback == null)  
  10. 10             {  
  11. 11                 return;  
  12. 12             }  
  13. 13   
  14. 14             // Move the feedback envelope and store the current mouse position   
  15. 15             IActiveView pActiveView = (IActiveView)m_pMap;  
  16. 16             m_pFeedback.MoveTo(pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y));  
  17. 17             m_pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);  
  18. 18         }  

11.完成新建对象,取得绘制的对象,并添加到图层中 :建议在Map.DblClick或Map.MouseDown(Button = 2)事件中调用本方法

[csharp] view plaincopy
  1.  1         /// <summary>  
  2.  2 /// 完成新建对象,取得绘制的对象,并添加到图层中  
  3.  3 /// 建议在Map.DblClick或Map.MouseDown(Button = 2)事件中调用本方法  
  4.  4 /// </summary>  
  5.  5         private void EndSketch()  
  6.  6         {  
  7.  7             IGeometry pGeom = null;  
  8.  8             IPointCollection pPointCollection = null;  
  9.  9   
  10. 10             // Create a new feature if possible   
  11. 11             if (m_pFeedback is INewMultiPointFeedback)  
  12. 12             {  
  13. 13                 INewMultiPointFeedback pMPFeed = (INewMultiPointFeedback)m_pFeedback;  
  14. 14                 pMPFeed.Stop();  
  15. 15                 pGeom = (IGeometry)m_pPointCollection;  
  16. 16             }  
  17. 17             else if (m_pFeedback is INewLineFeedback)  
  18. 18             {  
  19. 19                 INewLineFeedback pLineFeed = (INewLineFeedback)m_pFeedback;  
  20. 20                 pLineFeed.AddPoint(m_pPoint);  
  21. 21                 IPolyline pPolyLine = pLineFeed.Stop();  
  22. 22                 pPointCollection = (IPointCollection)pPolyLine;  
  23. 23                 if (pPointCollection.PointCount < 2)  
  24. 24                     MessageBox.Show("至少输入两个节点.""错误的线几何对象", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);  
  25. 25                 else  
  26. 26                     pGeom = (IGeometry)pPointCollection;  
  27. 27             }  
  28. 28             else if (m_pFeedback is INewPolygonFeedback)  
  29. 29             {  
  30. 30                 INewPolygonFeedback pPolyFeed = (INewPolygonFeedback)m_pFeedback;  
  31. 31                 pPolyFeed.AddPoint(m_pPoint);  
  32. 32                 IPolygon pPolygon = pPolyFeed.Stop();  
  33. 33                 if (pPolygon != null)  
  34. 34                     pPointCollection = (IPointCollection)pPolygon;  
  35. 35                 if (pPointCollection.PointCount < 3)  
  36. 36                     MessageBox.Show("至少输入三个节点.""错误的线几何对象", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);  
  37. 37                 else  
  38. 38                     pGeom = (IGeometry)pPointCollection;  
  39. 39             }  
  40. 40             CreateFeature(pGeom);  
  41. 41             m_pFeedback = null;  
  42. 42             m_bInUse = false;  
  43. 43         }  

12.查询当前图层中鼠标位置处的地图对象,建议在Map.MouseDown事件中调用本方法

[csharp] view plaincopy
  1.  1         /// <summary>  
  2.  2 /// 查询当前图层中鼠标位置处的地图对象  
  3.  3 /// 建议在Map.MouseDown事件中调用本方法  
  4.  4 /// </summary>  
  5.  5 /// <param name="x">鼠标X坐标,屏幕坐标</param>  
  6.  6 /// <param name="y">鼠标Y坐标,屏幕坐标</param>  
  7.  7         private void SelectMouseDown(int x, int y)  
  8.  8         {  
  9.  9             // Searches the map for features at the given point in the current layer   
  10. 10 // and selects them   
  11. 11   
  12. 12             m_pMap.ClearSelection();//清除地图中已选的要素  
  13. 13             if (m_pCurrentLayer == null)  
  14. 14             {  
  15. 15                 return;  
  16. 16             }  
  17. 17   
  18. 18             if ((IGeoFeatureLayer)m_pCurrentLayer == null)  
  19. 19             {  
  20. 20                 return;  
  21. 21             }  
  22. 22   
  23. 23             // Get the feature layer and class of the current layer   
  24. 24             IFeatureLayer pFeatureLayer = (IFeatureLayer)m_pCurrentLayer;  
  25. 25             IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;  
  26. 26             if (pFeatureClass == null)  
  27. 27             {  
  28. 28                 return;  
  29. 29             }  
  30. 30   
  31. 31             // Get the mouse down position in map coordinates   
  32. 32             IActiveView pActiveView = (IActiveView)m_pMap;  
  33. 33             IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);  
  34. 34             IGeometry pGeometry = pPoint;  
  35. 35   
  36. 36             // Use a four pixel buffer around the cursor for feature search   
  37. 37 // 设置查询缓冲区  
  38. 38             double length = ConvertPixelsToMapUnits(pActiveView, 4);  
  39. 39             ITopologicalOperator pTopo = (ITopologicalOperator)pGeometry;  
  40. 40             IGeometry pBuffer = pTopo.Buffer(length);  
  41. 41             pGeometry = (IGeometry)pBuffer.Envelope;  
  42. 42   
  43. 43             // up a Filter specific to this layer    
  44. 44 //设置过滤器对象  
  45. 45             ISpatialFilter pSpatialFilter = new SpatialFilter();  
  46. 46             pSpatialFilter.Geometry = pGeometry;  
  47. 47             switch (pFeatureClass.ShapeType)  
  48. 48             {  
  49. 49                 case esriGeometryType.esriGeometryPoint:  
  50. 50                     pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;  
  51. 51                     break;  
  52. 52                 case esriGeometryType.esriGeometryPolyline:  
  53. 53                     pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;  
  54. 54                     break;  
  55. 55                 case esriGeometryType.esriGeometryPolygon:  
  56. 56                     pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;  
  57. 57                     break;  
  58. 58             }  
  59. 59             pSpatialFilter.GeometryField = pFeatureClass.ShapeFieldName;  
  60. 60             IQueryFilter pFilter = pSpatialFilter;  
  61. 61   
  62. 62             // Do the search   
  63. 63 // 查询  
  64. 64             IFeatureCursor pCursor = pFeatureLayer.Search(pFilter, false);  
  65. 65   
  66. 66             // and select the features on the map   
  67. 67 // 在地图上高亮显示查询结果  
  68. 68             IFeature pFeature = pCursor.NextFeature();  
  69. 69             while (pFeature != null)  
  70. 70             {  
  71. 71                 m_pMap.SelectFeature(m_pCurrentLayer, pFeature);  
  72. 72                 pFeature = pCursor.NextFeature();  
  73. 73             }  
  74. 74             pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, nullnull);  
  75. 75         }  

13.编辑当前图层中鼠标击中的地图对象(开始编辑), 如果为点对象,可进行位置移动,如果为线对象或面对象,可进行节点编辑 : 建议在Map.MouseDown事件中调用本方法

[csharp] view plaincopy
  1.   1         /// <summary>  
  2.   2 /// 编辑当前图层中鼠标击中的地图对象(开始编辑),  
  3.   3 /// 如果为点对象,可进行位置移动,如果为线对象或面对象,可进行节点编辑  
  4.   4 /// 建议在Map.MouseDown事件中调用本方法  
  5.   5 /// </summary>  
  6.   6 /// <param name="x">鼠标X坐标,屏幕坐标</param>  
  7.   7 /// <param name="y">鼠标Y坐标,屏幕坐标</param>  
  8.   8 /// <returns></returns>  
  9.   9         private void EditFeature(int x, int y)  
  10.  10         {  
  11.  11             // Searches for features under the coordinate provided and starts an edit   
  12.  12 // operation on the first one found.   
  13.  13             IPoint pHitPoint = null;  
  14.  14             double hitDist = 0;  
  15.  15             int partIndex = 0;  
  16.  16             int vertexIndex = 0;  
  17.  17             int vertexOffset = 0;  
  18.  18             bool vertex = false;  
  19.  19   
  20.  20             // Use the first feature in the selection   
  21.  21 // 取得鼠标击中的第一个对象  
  22.  22             SelectMouseDown(x, y);  
  23.  23             IEnumFeature pSelected = (IEnumFeature)m_pMap.FeatureSelection;  
  24.  24             IFeature pFeature = pSelected.Next();  
  25.  25             if (pFeature == null)  
  26.  26             {  
  27.  27                 return;  
  28.  28             }  
  29.  29   
  30.  30             IActiveView pActiveView = (IActiveView)m_pMap;  
  31.  31             IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);  
  32.  32   
  33.  33             // Tolerance in pixels for line hits   
  34.  34 // 节点空间查询容差  
  35.  35             double tol = ConvertPixelsToMapUnits(pActiveView, 4);  
  36.  36   
  37.  37             // The feedback action / edit action depends on the geometry type   
  38.  38 // and the location of point within the geometry   
  39.  39             IGeometry pGeom = pFeature.Shape;  
  40.  40             IObjectClass pObjectClass = pFeature.Class;  
  41.  41             m_pEditFeature = pFeature;  
  42.  42   
  43.  43             switch (pGeom.GeometryType)  
  44.  44             {  
  45.  45                 case esriGeometryType.esriGeometryPoint:  
  46.  46                     m_pFeedback = new MovePointFeedback();  
  47.  47                     m_pFeedback.Display = pActiveView.ScreenDisplay;  
  48.  48                     IMovePointFeedback pPointMove = (IMovePointFeedback)m_pFeedback;  
  49.  49                     pPointMove.Start((IPoint)pGeom, pPoint);  
  50.  50                     break;  
  51.  51   
  52.  52                 case esriGeometryType.esriGeometryPolyline:  
  53.  53                     if (TestGeometryHit(tol, pPoint, pFeature, ref pHitPoint, ref hitDist,  
  54.  54                         ref partIndex, ref vertexIndex, ref vertexOffset, ref vertex))  
  55.  55                     {  
  56.  56                         if (!vertex)  
  57.  57                         {  
  58.  58                             // Get the path, add a point to it and vertex edit that newly added point   
  59.  59                             IGeometryCollection pGeomColn = (IGeometryCollection)pGeom;  
  60.  60                             IPath pPath = (IPath)pGeomColn.get_Geometry(partIndex);  
  61.  61                             IPointCollection pPointColn = (IPointCollection)pPath;  
  62.  62                             long numVertices = pPointColn.PointCount;  
  63.  63   
  64.  64                             object Missing = Type.Missing;  
  65.  65                             object val;  
  66.  66                             if (vertexIndex == 0)  
  67.  67                             {  
  68.  68                                 val = 1;  
  69.  69                                 pPointColn.AddPoint(pPoint, ref val, ref Missing);  
  70.  70                             }  
  71.  71                             else  
  72.  72                             {  
  73.  73                                 val = vertexIndex;  
  74.  74                                 pPointColn.AddPoint(pPoint, ref Missing, ref val);  
  75.  75                             }  
  76.  76   
  77.  77                             // Reset the index pointer to the new index   
  78.  78                             TestGeometryHit(tol, pPoint, pFeature, ref pHitPoint, ref hitDist, ref partIndex, ref vertexIndex, ref vertexOffset, ref vertex);  
  79.  79                         }  
  80.  80                         m_pFeedback = new LineMovePointFeedback();  
  81.  81                         m_pFeedback.Display = pActiveView.ScreenDisplay;  
  82.  82                         ILineMovePointFeedback pLineMove = (ILineMovePointFeedback)m_pFeedback;  
  83.  83                         pLineMove.Start((IPolyline)pGeom, vertexIndex, pPoint);  
  84.  84                     }  
  85.  85                     else  
  86.  86                     {  
  87.  87                         return;  
  88.  88                     }  
  89.  89                     //  
  90.  90                     break;  
  91.  91   
  92.  92                 case esriGeometryType.esriGeometryPolygon:  
  93.  93                     if (TestGeometryHit(tol, pPoint, pFeature, ref pHitPoint, ref hitDist,  
  94.  94                         ref partIndex, ref vertexIndex, ref vertexOffset, ref vertex))  
  95.  95                     {  
  96.  96                         if (!vertex)  
  97.  97                         {  
  98.  98                             // Get the path, add a point to it and vertex edit that newly added point   
  99.  99                             IGeometryCollection pGeomColn = (IGeometryCollection)pGeom;  
  100. 100                             IPath pPath = (IPath)pGeomColn.get_Geometry(partIndex);  
  101. 101                             IPointCollection pPointColn = (IPointCollection)pPath;  
  102. 102                             long numVertices = pPointColn.PointCount;  
  103. 103   
  104. 104                             // Rethe index pointer to the new index   
  105. 105                             object Missing = Type.Missing;  
  106. 106                             object val;  
  107. 107                             if (vertexIndex == 0)  
  108. 108                             {  
  109. 109                                 val = 1;  
  110. 110                                 pPointColn.AddPoint(pPoint, ref val, ref Missing);  
  111. 111                             }  
  112. 112                             else  
  113. 113                             {  
  114. 114                                 val = vertexIndex;  
  115. 115                                 pPointColn.AddPoint(pPoint, ref Missing, ref val);  
  116. 116                             }  
  117. 117   
  118. 118                             // Reset the index pointer to the new index   
  119. 119                             TestGeometryHit(tol, pPoint, pFeature, ref pHitPoint, ref hitDist, ref partIndex, ref vertexIndex, ref vertexOffset, ref vertex);  
  120. 120                         }  
  121. 121                         m_pFeedback = new PolygonMovePointFeedback();  
  122. 122                         m_pFeedback.Display = pActiveView.ScreenDisplay;  
  123. 123                         IPolygonMovePointFeedback pPolyMove = (IPolygonMovePointFeedback)m_pFeedback;  
  124. 124                         pPolyMove.Start((IPolygon)pGeom, vertexIndex + vertexOffset, pPoint);  
  125. 125                     }  
  126. 126                     else  
  127. 127                         return;  
  128. 128                     break;  
  129. 129             }  
  130. 130   
  131. 131             return;  
  132. 132         }  

14.编辑地图对象过程中的鼠标移动事件, 如果为点对象,进行位置移动;如果为线对象或面对象,进行节点移动:建议在Map.MouseMove事件中调用本方法

[csharp] view plaincopy
  1.  1         /// <summary>  
  2.  2 /// 编辑地图对象过程中的鼠标移动事件,  
  3.  3 /// 如果为点对象,进行位置移动  
  4.  4 /// 如果为线对象或面对象,进行节点移动  
  5.  5 /// 建议在Map.MouseMove事件中调用本方法  
  6.  6 /// </summary>  
  7.  7 /// <param name="x">鼠标X坐标,屏幕坐标</param>  
  8.  8 /// <param name="y">鼠标Y坐标,屏幕坐标</param>  
  9.  9         private void FtrEditMouseMove(int x, int y)  
  10. 10         {  
  11. 11             // Moves the edit feedback object along with the mouse.   
  12. 12             if (m_pFeedback == null)  
  13. 13             {  
  14. 14                 return;  
  15. 15             }  
  16. 16   
  17. 17             IActiveView pActiveView = (IActiveView)m_pMap;  
  18. 18             IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);  
  19. 19             m_pFeedback.MoveTo(pPoint);  
  20. 20         }  

15.结束feature的编辑

[csharp] view plaincopy
  1.  1         /// <summary>  
  2.  2 /// 结束feature的编辑  
  3.  3 /// </summary>  
  4.  4 /// <param name="x"></param>  
  5.  5 /// <param name="y"></param>  
  6.  6         private void EndFtrEdit(int x, int y)  
  7.  7         {  
  8.  8             // Uses the feedback object//s geometry to rethe geometry on the feature   
  9.  9 // being edited.   
  10. 10   
  11. 11 // if (no feedback no edit   
  12. 12             if (m_pFeedback == null)  
  13. 13             {  
  14. 14                 return;  
  15. 15             }  
  16. 16   
  17. 17             IActiveView pActiveView = (IActiveView)m_pMap;  
  18. 18             IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);  
  19. 19   
  20. 20             if (m_pFeedback is IMovePointFeedback)  
  21. 21             {  
  22. 22                 IMovePointFeedback pPointMove = (IMovePointFeedback)m_pFeedback;  
  23. 23                 IGeometry pGeometry = pPointMove.Stop();  
  24. 24                 UpdateFeature(m_pEditFeature, pGeometry);  
  25. 25             }  
  26. 26             else if (m_pFeedback is ILineMovePointFeedback)  
  27. 27             {  
  28. 28                 ILineMovePointFeedback pLineMove = (ILineMovePointFeedback)m_pFeedback;  
  29. 29                 IGeometry pGeometry = pLineMove.Stop();  
  30. 30                 UpdateFeature(m_pEditFeature, pGeometry);  
  31. 31             }  
  32. 32             else if (m_pFeedback is IPolygonMovePointFeedback)  
  33. 33             {  
  34. 34                 IPolygonMovePointFeedback pPolyMove = (IPolygonMovePointFeedback)m_pFeedback;  
  35. 35                 IGeometry pGeometry = pPolyMove.Stop();  
  36. 36                 UpdateFeature(m_pEditFeature, pGeometry);  
  37. 37             }  
  38. 38   
  39. 39             m_pFeedback = null;  
  40. 40             pActiveView.Refresh();  
  41. 41         }  

16.移动当前图层中鼠标击中地图对象的位置(开始移动):建议在Map.MouseDown事件中调用本方法

[csharp] view plaincopy
  1.  1         /// <summary>  
  2.  2 /// 移动当前图层中鼠标击中地图对象的位置(开始移动)  
  3.  3 /// 建议在Map.MouseDown事件中调用本方法  
  4.  4 /// </summary>  
  5.  5 /// <param name="x">鼠标X坐标,屏幕坐标</param>  
  6.  6 /// <param name="y">鼠标Y坐标,屏幕坐标</param>  
  7.  7 /// <returns></returns>  
  8.  8         public bool MoveFeatureMouseDown(int x, int y)  
  9.  9         {  
  10. 10             try  
  11. 11             {  
  12. 12                 m_pMap.ClearSelection();  
  13. 13   
  14. 14                 SelectMouseDown(x, y);  
  15. 15                 IEnumFeature pSelected = (IEnumFeature)m_pMap.FeatureSelection;  
  16. 16                 IFeature pFeature = pSelected.Next();  
  17. 17                 if (pFeature == nullreturn false;  
  18. 18   
  19. 19                 IActiveView pActiveView = (IActiveView)m_pMap;  
  20. 20                 IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);  
  21. 21   
  22. 22                 IGeometry pGeom = pFeature.Shape;  
  23. 23                 m_pEditFeature = pFeature;  
  24. 24   
  25. 25                 switch (pGeom.GeometryType)  
  26. 26                 {  
  27. 27                     case esriGeometryType.esriGeometryPoint:  
  28. 28                         m_pFeedback = new MovePointFeedbackClass();  
  29. 29                         m_pFeedback.Display = pActiveView.ScreenDisplay;  
  30. 30                         IMovePointFeedback pPointMove = (IMovePointFeedback)m_pFeedback;  
  31. 31                         pPointMove.Start((IPoint)pGeom, pPoint);  
  32. 32                         break;  
  33. 33                     case esriGeometryType.esriGeometryPolyline:  
  34. 34   
  35. 35                         m_pFeedback = new MoveLineFeedbackClass();  
  36. 36                         m_pFeedback.Display = pActiveView.ScreenDisplay;  
  37. 37                         IMoveLineFeedback pLineMove = (IMoveLineFeedback)m_pFeedback;  
  38. 38                         pLineMove.Start((IPolyline)pGeom, pPoint);  
  39. 39                         break;  
  40. 40                     case esriGeometryType.esriGeometryPolygon:  
  41. 41                         m_pFeedback = new MovePolygonFeedbackClass();  
  42. 42                         m_pFeedback.Display = pActiveView.ScreenDisplay;  
  43. 43                         IMovePolygonFeedback pPolyMove = (IMovePolygonFeedback)m_pFeedback;  
  44. 44                         pPolyMove.Start((IPolygon)pGeom, pPoint);  
  45. 45                         break;  
  46. 46                 }  
  47. 47                 return true;  
  48. 48             }  
  49. 49             catch (Exception e)  
  50. 50             {  
  51. 51                 Console.WriteLine(e.Message.ToString());  
  52. 52                 return false;  
  53. 53             }  
  54. 54         }  

17.移动地图对象过程中的鼠标移动事件:建议在Map.MouseMove事件中调用本方法

[csharp] view plaincopy
  1.  1         /// <summary>  
  2.  2 /// 移动地图对象过程中的鼠标移动事件  
  3.  3 /// 建议在Map.MouseMove事件中调用本方法  
  4.  4 /// </summary>  
  5.  5 /// <param name="x">鼠标X坐标,屏幕坐标</param>  
  6.  6 /// <param name="y">鼠标Y坐标,屏幕坐标</param>  
  7.  7         public void MoveFeatureMouseMove(int x, int y)  
  8.  8         {  
  9.  9             try  
  10. 10             {  
  11. 11                 if (m_pFeedback == nullreturn;  
  12. 12   
  13. 13                 IActiveView pActiveView = (IActiveView)m_pMap;  
  14. 14                 IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);  
  15. 15                 m_pFeedback.MoveTo(pPoint);  
  16. 16             }  
  17. 17             catch (Exception e)  
  18. 18             {  
  19. 19                 Console.WriteLine(e.Message.ToString());  
  20. 20             }  
  21. 21         }  

18.完成地图对象移动,取得移动后的对象,并将其更新到图层中:建议在Map.MouseUp事件中调用本方法

[csharp] view plaincopy
  1.  1         /// <summary>  
  2.  2 /// 完成地图对象移动,取得移动后的对象,并将其更新到图层中  
  3.  3 /// 建议在Map.MouseUp事件中调用本方法  
  4.  4 /// </summary>  
  5.  5         public void MoveFeatureEnd()  
  6.  6         {  
  7.  7             IGeometry pGeometry;  
  8.  8   
  9.  9             try  
  10. 10             {  
  11. 11                 if (m_pFeedback == nullreturn;  
  12. 12   
  13. 13                 if (m_pFeedback is IMovePointFeedback)  
  14. 14                 {  
  15. 15                     IMovePointFeedback pPointMove = (IMovePointFeedback)m_pFeedback;  
  16. 16                     pGeometry = pPointMove.Stop();  
  17. 17                     UpdateFeature(m_pEditFeature, pGeometry);  
  18. 18                 }  
  19. 19                 else if (m_pFeedback is IMoveLineFeedback)  
  20. 20                 {  
  21. 21                     IMoveLineFeedback pLineMove = (IMoveLineFeedback)m_pFeedback;  
  22. 22                     pGeometry = pLineMove.Stop();  
  23. 23                     UpdateFeature(m_pEditFeature, pGeometry);  
  24. 24                 }  
  25. 25                 else if (m_pFeedback is IMovePolygonFeedback)  
  26. 26                 {  
  27. 27                     IMovePolygonFeedback pPolyMove = (IMovePolygonFeedback)m_pFeedback;  
  28. 28                     pGeometry = pPolyMove.Stop();  
  29. 29                     UpdateFeature(m_pEditFeature, pGeometry);  
  30. 30                 }  
  31. 31   
  32. 32                 m_pFeedback = null;  
  33. 33                 IActiveView pActiveView = (IActiveView)m_pMap;  
  34. 34                 pActiveView.Refresh();  
  35. 35             }  
  36. 36             catch (Exception e)  
  37. 37             {  
  38. 38                 Console.WriteLine(e.Message.ToString());  
  39. 39             }  
  40. 40         }  

总结:终于结束了,感觉通过可视化来编辑空间数据需要做太多的工作,上面把要做的工作几乎都秒到了,至于具体流程这个只需要简单组织一下逻辑就可以了。更强大的空间数据编辑功能有待于我们更加活跃的思维去创造!OK!今天就到这里了吧!情人节已过,各位coder们赶快回来编程吧!

原创粉丝点击