现在的位置: 首页 > 综合 > 正文

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

2012年07月27日 ⁄ 综合 ⁄ 共 12895字 ⁄ 字号 评论关闭

我的新浪微博:http://weibo.com/freshairbrucewoo

欢迎大家相互交流,共同提高技术。

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

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

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

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

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

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

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

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

 1         /// <summary>
2 /// 向图层中更新新的地图对象,并使之处于选中状态
3 /// </summary>
4 /// <param name="pFeature"></param>
5 /// <param name="pGeometry"></param>
6 private void UpdateFeature(IFeature pFeature, IGeometry pGeometry)
7 {
8 // Make sure we are actually editing this layer. If not give a warning.
9 IDataset pDataset = (IDataset)pFeature.Class;
10 IWorkspaceEdit pWorkspaceEdit = (IWorkspaceEdit)pDataset.Workspace;
11 if (!pWorkspaceEdit.IsBeingEdited())
12 {
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 "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
15 }
16
17 // If all tests succeed allow feature edits to be saved
18 pWorkspaceEdit.StartEditOperation();
19 pFeature.Shape = pGeometry;
20 pFeature.Store();
21 pWorkspaceEdit.StopEditOperation();
22 }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

抱歉!评论已关闭.