上一篇http://www.BkJia.com/kf/201202/119588.html介紹了空間數據編輯一部分實現,今天繼續完成剩余的部分實現。
1.根據選擇編輯任務的不同顯示不同形狀的鼠標,以便指示相應任務方便編輯操作
[csharp]
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.選擇需要的圖層並且在地圖編輯控件中顯示出來
[csharp]
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.測試是否擊中地圖對象或地圖對象上的節點
[csharp]
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.向圖層中更新新的地圖對象,並使之處於選中狀態
[csharp]
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.屏幕坐標轉換為地圖坐標
[csharp]
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.處理地圖控件上的目標按下事件
[csharp]
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.處理地圖控件上的鼠標移動事件
[csharp]
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.處理地圖控件上的鼠標按下事件
[csharp]
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方法完成對象創建 。
[csharp]
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事件中調用本方法
[csharp]
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)事件中調用本方法
[csharp]
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事件中調用本方法
[csharp]
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 }
13.編輯當前圖層中鼠標擊中的地圖對象(開始編輯), 如果為點對象,可進行位置移動,如果為線對象或面對象,可進行節點編輯 : 建議在Map.MouseDown事件中調用本方法
[csharp]
1 /// <summary>
2 /// 編輯當前圖層中鼠標擊中的地圖對象(開始編輯),
3 /// 如果為點對象,可進行位置移動,如果為線對象或面對象,可進行節點編輯
4 /// 建議在Map.MouseDown事件中調用本方法
5 /// </summary>
6 /// <param name="x">鼠標X坐標,屏幕坐標</param>
7 /// <param name="y">鼠標Y坐標,屏幕坐標</param>
8 /// <returns></returns>
9 private void EditFeature(int x, int y)
10 {
11 // Searches for features under the coordinate provided and starts an edit
12 // operation on the first one found.
13 IPoint pHitPoint = null;
14 double hitDist = 0;
15 int partIndex = 0;
16 int vertexIndex = 0;
17 int vertexOffset = 0;
18 bool vertex = false;
19
20 // Use the first feature in the selection
21 // 取得鼠標擊中的第一個對象
22 SelectMouseDown(x, y);
23 IEnumFeature pSelected = (IEnumFeature)m_pMap.FeatureSelection;
24 IFeature pFeature = pSelected.Next();
25 if (pFeature == null)
26 {
27 return;
28 }
29
30 IActiveView pActiveView = (IActiveView)m_pMap;
31 IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
32
33 // Tolerance in pixels for line hits
34 // 節點空間查詢容差
35 double tol = ConvertPixelsToMapUnits(pActiveView, 4);
36
37 // The feedback action / edit action depends on the geometry type
38 // and the location of point within the geometry
39 IGeometry pGeom = pFeature.Shape;
40 IObjectClass pObjectClass = pFeature.Class;
41 m_pEditFeature = pFeature;
42
43 switch (pGeom.GeometryType)
44 {
45 case esriGeometryType.esriGeometryPoint:
46 m_pFeedback = new MovePointFeedback();
47 m_pFeedback.Display = pActiveView.ScreenDisplay;
48 IMovePointFeedback pPointMove = (IMovePointFeedback)m_pFeedback;
49 pPointMove.Start((IPoint)pGeom, pPoint);
50 break;
51
52 case esriGeometryType.esriGeometryPolyline:
53 if (TestGeometryHit(tol, pPoint, pFeature, ref pHitPoint, ref hitDist,
54 ref partIndex, ref vertexIndex, ref vertexOffset, ref vertex))
55 {
56 if (!vertex)
57 {
58 // Get the path, add a point to it and vertex edit that newly added point
59 IGeometryCollection pGeomColn = (IGeometryCollection)pGeom;
60 IPath pPath = (IPath)pGeomColn.get_Geometry(partIndex);
61 IPointCollection pPointColn = (IPointCollection)pPath;
62 long numVertices = pPointColn.PointCount;
63
64 object Missing = Type.Missing;
65 object val;
66 if (vertexIndex == 0)
67 {
68 val = 1;
69 pPointColn.AddPoint(pPoint, ref val, ref Missing);
70 }
71 else
72 {
73 val = vertexIndex;
74 pPointColn.AddPoint(pPoint, ref Missing, ref val);
75 }
76
77 // Reset the index pointer to the new index
78 TestGeometryHit(tol, pPoint, pFeature, ref pHitPoint, ref hitDist, ref partIndex, ref vertexIndex, ref vertexOffset, ref vertex);
79 }
80 m_pFeedback = new LineMovePointFeedback();
81 m_pFeedback.Display = pActiveView.ScreenDisplay;
82 ILineMovePointFeedback pLineMove = (ILineMovePointFeedback)m_pFeedback;
83 pLineMove.Start((IPolyline)pGeom, vertexIndex, pPoint);
84 }
85 else
86 {
87 return;
88 }
89 //
90 break;
91
92 case esriGeometryType.esriGeometryPolygon:
93 if (TestGeometryHit(tol, pPoint, pFeature, ref pHitPoint, ref hitDist,
94 ref partIndex, ref vertexIndex, ref vertexOffset, ref vertex))
95 {
96 if (!vertex)
97 {
98 // Get the path, add a point to it and vertex edit that newly added point
99 IGeometryCollection pGeomColn = (IGeometryCollection)pGeom;
100 IPath pPath = (IPath)pGeomColn.get_Geometry(partIndex);
101 IPointCollection pPointColn = (IPointCollection)pPath;
102 long numVertices = pPointColn.PointCount;
103
104 // Rethe index pointer to the new index
105 object Missing = Type.Missing;
106 object val;
107 if (vertexIndex == 0)
108 {
109 val = 1;
110 pPointColn.AddPoint(pPoint, ref val, ref Missing);
111 }
112 else
113 {
114 val = vertexIndex;
115 pPointColn.AddPoint(pPoint, ref Missing, ref val);
116 }
117
118 // Reset the index pointer to the new index
119 TestGeometryHit(tol, pPoint, pFeature, ref pHitPoint, ref hitDist, ref partIndex, ref vertexIndex, ref vertexOffset, ref vertex);
120 }
121 m_pFeedback = new PolygonMovePointFeedback();
122 m_pFeedback.Display = pActiveView.ScreenDisplay;
123 IPolygonMovePointFeedback pPolyMove = (IPolygonMovePointFeedback)m_pFeedback;
124 pPolyMove.Start((IPolygon)pGeom, vertexIndex + vertexOffset, pPoint);
125 }
126 else
127 return;
128 break;
129 }
130
131 return;
132 }
14.編輯地圖對象過程中的鼠標移動事件, 如果為點對象,進行位置移動;如果為線對象或面對象,進行節點移動:建議在Map.MouseMove事件中調用本方法
[csharp]
1 /// <summary>
2 /// 編輯地圖對象過程中的鼠標移動事件,
3 /// 如果為點對象,進行位置移動
4 /// 如果為線對象或面對象,進行節點移動
5 /// 建議在Map.MouseMove事件中調用本方法
6 /// </summary>
7 /// <param name="x">鼠標X坐標,屏幕坐標</param>
8 /// <param name="y">鼠標Y坐標,屏幕坐標</param>
9 private void FtrEditMouseMove(int x, int y)
10 {
11 // Moves the edit feedback object along with the mouse.
12 if (m_pFeedback == null)
13 {
14 return;
15 }
16
17 IActiveView pActiveView = (IActiveView)m_pMap;
18 IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
19 m_pFeedback.MoveTo(pPoint);
20 }
15.結束feature的編輯
[csharp]
1 /// <summary>
2 /// 結束feature的編輯
3 /// </summary>
4 /// <param name="x"></param>
5 /// <param name="y"></param>
6 private void EndFtrEdit(int x, int y)
7 {
8 // Uses the feedback object//s geometry to rethe geometry on the feature
9 // being edited.
10
11 // if (no feedback no edit
12 if (m_pFeedback == null)
13 {
14 return;
15 }
16
17 IActiveView pActiveView = (IActiveView)m_pMap;
18 IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
19
20 if (m_pFeedback is IMovePointFeedback)
21 {
22 IMovePointFeedback pPointMove = (IMovePointFeedback)m_pFeedback;
23 IGeometry pGeometry = pPointMove.Stop();
24 UpdateFeature(m_pEditFeature, pGeometry);
25 }
26 else if (m_pFeedback is ILineMovePointFeedback)
27 {
28 ILineMovePointFeedback pLineMove = (ILineMovePointFeedback)m_pFeedback;
29 IGeometry pGeometry = pLineMove.Stop();
30 UpdateFeature(m_pEditFeature, pGeometry);
31 }
32 else if (m_pFeedback is IPolygonMovePointFeedback)
33 {
34 IPolygonMovePointFeedback pPolyMove = (IPolygonMovePointFeedback)m_pFeedback;
35 IGeometry pGeometry = pPolyMove.Stop();
36 UpdateFeature(m_pEditFeature, pGeometry);
37 }
38
39 m_pFeedback = null;
40 pActiveView.Refresh();
41 }
16.移動當前圖層中鼠標擊中地圖對象的位置(開始移動):建議在Map.MouseDown事件中調用本方法
[csharp]
1 /// <summary>
2 /// 移動當前圖層中鼠標擊中地圖對象的位置(開始移動)
3 /// 建議在Map.MouseDown事件中調用本方法
4 /// </summary>
5 /// <param name="x">鼠標X坐標,屏幕坐標</param>
6 /// <param name="y">鼠標Y坐標,屏幕坐標</param>
7 /// <returns></returns>
8 public bool MoveFeatureMouseDown(int x, int y)
9 {
10 try
11 {
12 m_pMap.ClearSelection();
13
14 SelectMouseDown(x, y);
15 IEnumFeature pSelected = (IEnumFeature)m_pMap.FeatureSelection;
16 IFeature pFeature = pSelected.Next();
17 if (pFeature == null) return false;
18
19 IActiveView pActiveView = (IActiveView)m_pMap;
20 IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
21
22 IGeometry pGeom = pFeature.Shape;
23 m_pEditFeature = pFeature;
24
25 switch (pGeom.GeometryType)
26 {
27 case esriGeometryType.esriGeometryPoint:
28 m_pFeedback = new MovePointFeedbackClass();
29 m_pFeedback.Display = pActiveView.ScreenDisplay;
30 IMovePointFeedback pPointMove = (IMovePointFeedback)m_pFeedback;
31 pPointMove.Start((IPoint)pGeom, pPoint);
32 break;
33 case esriGeometryType.esriGeometryPolyline:
34
35 m_pFeedback = new MoveLineFeedbackClass();
36 m_pFeedback.Display = pActiveView.ScreenDisplay;
37 IMoveLineFeedback pLineMove = (IMoveLineFeedback)m_pFeedback;
38 pLineMove.Start((IPolyline)pGeom, pPoint);
39 break;
40 case esriGeometryType.esriGeometryPolygon:
41 m_pFeedback = new MovePolygonFeedbackClass();
42 m_pFeedback.Display = pActiveView.ScreenDisplay;
43 IMovePolygonFeedback pPolyMove = (IMovePolygonFeedback)m_pFeedback;
44 pPolyMove.Start((IPolygon)pGeom, pPoint);
45 break;
46 }
47 return true;
48 }
49 catch (Exception e)
50 {
51 Console.WriteLine(e.Message.ToString());
52 return false;
53 }
54 }
17.移動地圖對象過程中的鼠標移動事件:建議在Map.MouseMove事件中調用本方法
[csharp]
1 /// <summary>
2 /// 移動地圖對象過程中的鼠標移動事件
3 /// 建議在Map.MouseMove事件中調用本方法
4 /// </summary>
5 /// <param name="x">鼠標X坐標,屏幕坐標</param>
6 /// <param name="y">鼠標Y坐標,屏幕坐標</param>
7 public void MoveFeatureMouseMove(int x, int y)
8 {
9 try
10 {
11 if (m_pFeedback == null) return;
12
13 IActiveView pActiveView = (IActiveView)m_pMap;
14 IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
15 m_pFeedback.MoveTo(pPoint);
16 }
17 catch (Exception e)
18 {
19 Console.WriteLine(e.Message.ToString());
20 }
21 }
18.完成地圖對象移動,取得移動後的對象,並將其更新到圖層中:建議在Map.MouseUp事件中調用本方法
[csharp]
1 /// <summary>
2 /// 完成地圖對象移動,取得移動後的對象,並將其更新到圖層中
3 /// 建議在Map.MouseUp事件中調用本方法
4 /// </summary>
5 public void MoveFeatureEnd()
6 {
7 IGeometry pGeometry;
8
9 try
10 {
11 if (m_pFeedback == null) return;
12
13 if (m_pFeedback is IMovePointFeedback)
14 {
15 IMovePointFeedback pPointMove = (IMovePointFeedback)m_pFeedback;
16 pGeometry = pPointMove.Stop();
17 UpdateFeature(m_pEditFeature, pGeometry);
18 }
19 else if (m_pFeedback is IMoveLineFeedback)
20 {
21 IMoveLineFeedback pLineMove = (IMoveLineFeedback)m_pFeedback;
22 pGeometry = pLineMove.Stop();
23 UpdateFeature(m_pEditFeature, pGeometry);
24 }
25 else if (m_pFeedback is IMovePolygonFeedback)
26 {
27 IMovePolygonFeedback pPolyMove = (IMovePolygonFeedback)m_pFeedback;
28 pGeometry = pPolyMove.Stop();
29 UpdateFeature(m_pEditFeature, pGeometry);
30 }
31
32 m_pFeedback = null;
33 IActiveView pActiveView = (IActiveView)m_pMap;
34 pActiveView.Refresh();
35 }
36 catch (Exception e)
37 {
38 Console.WriteLine(e.Message.ToString());
39 }
40 }
總結:終於結束了,感覺通過可視化來編輯空間數據需要做太多的工作,上面把要做的工作幾乎都秒到了,至於具體流程這個只需要簡單組織一下邏輯就可以了。更強大的空間數據編輯功能有待於我們更加活躍的思維去創造!OK!今天就到這裡了吧!情人節已過,各位coder們趕快回來編程吧!
摘自 BruceWoo的專欄