基于插件技术的GIS应用框架(C# + ArcEngine9.3)(八)
--------------------------插件初始化(4)
上一小节中,我们介绍了命令插件如何调用地图编辑引擎来实现相应的编辑操作;与此相类似,我们同样可以通过编辑引擎接口设置编辑引擎当前的编辑任务,草图工具则通过读取框架对象的当前编辑任务来创建不同类型的FeedBack,从而绘制出草图,并输出这个草图的Geometry对象返回给编辑任务,编辑任务则通过获取草图工具输出的Geometry,来进行相应的图形处理。
编辑任务 - 分割图形,如何实现呢?首先我们看分割图形任务的实现类,代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Windows.Forms;
using esriCarto;
using esriControls;
using esriSystem;
using esriDisplay;
using esriGeometry;
using esriGeoDatabase;
using
AxeMap.AxeMapEngine;
using AxeMap.Library;
using AxeMap.AxeMapEngine.Interface;
namespace
AxeMap.AxeMapEngine.Implement
public class
AxCutFeature : IAxEditTask
private IAxApplication _App;
/// <summary>
/// Name
/// </summary>
public string Name
get
return "Cut Feature";
}
/// <summary>
/// Enabled
/// </summary>
public bool Enabled
get
esriGeometryType pType;
if ((_App.MapEngine.CurrentFeatureLayer == null) ||
(!_App.MapEngine.IsBeingEdited))
return false;
else
pType =
_App.MapEngine.CurrentFeatureLayer.FeatureClass.ShapeType;
if ((pType == esriGeometryType.esriGeometryPolygon) || (pType ==
esriGeometryType.esriGeometryPolyline))
return (_App.MapEngine.CurrentFeatureLayer as
IFeatureSelection).SelectionSet.Count > 0;
else
return false;
}
}
/// <summary>
/// GeometyType
/// </summary>
public esriGeometry.esriGeometryType GeometyType
get
return esriGeometryType.esriGeometryPolyline;
}
/// <summary>
/// OnCreate
/// </summary>
public void OnCreate(IAxApplication hook)
_App = hook;
/// <summary>
/// OnFinishSketch
/// </summary>
public void OnFinishSketch(esriGeometry.IGeometry
SketchGeometry)
esriGeometryType pType;
IFeatureClass pClass;
ISelectionSet pSelSet;
ICursor pCur;
IFeature pFea, pNewFea = null;
IGeometry pCutGeo = null, pLGeo = null, pRGeo = null, pNewGeo =
null, pBufGeo = null;
bool bFlag, bCutHappnend =
false;
int i;
IScreenDisplay pDisp;
double dLen;
//------------------------
IGeometryBag exteriorRings;
IEnumGeometry exteriorRingsEnum;
IRing currentExteriorRing;
//------------------------
if (!Enabled)
return;
if (SketchGeometry == null)
return;
pType = SketchGeometry.GeometryType;
if (pType != esriGeometryType.esriGeometryPolyline)
return;
}
pDisp = (_App.FocusMap as
IActiveView).ScreenDisplay;
_App.MapEngine.StartOperation();
try
bCutHappnend = false;
pClass = _App.MapEngine.CurrentFeatureLayer.FeatureClass;
pType = pClass.ShapeType;
pSelSet = (_App.MapEngine.CurrentFeatureLayer as
IFeatureSelection).SelectionSet;
pSelSet.Search(null, false, out
pCur);
_App.MapControl.Map.ClearSelection();
pFea = (pCur as IFeatureCursor).NextFeature();
while (pFea != null)
pLGeo = null;
pRGeo = null;
bFlag = false;
pCutGeo = pFea.Shape;
(SketchGeometry as ITopologicalOperator).Simplify();
(pCutGeo as ITopologicalOperator).Simplify();
(pCutGeo as ITopologicalOperator).Cut(SketchGeometry as IPolyline,
out pLGeo, out pRGeo);
if ((pLGeo == null) || (pRGeo == null))
continue;
(pLGeo as ITopologicalOperator).Simplify();
(pRGeo as ITopologicalOperator).Simplify();
if (pType == esriGeometryType.esriGeometryPolygon)
exteriorRings = (pLGeo as
IPolygon4).ExteriorRingBag;
//获取left所有的ExteriorRing
exteriorRingsEnum = exteriorRings as IEnumGeometry;
currentExteriorRing = exteriorRingsEnum.Next() as
IRing;//取一个外环
while (currentExteriorRing !=
null) //处理外环
{
pNewGeo =
Library.Geometry.CreatePolygonFromRing(currentExteriorRing);
pBufGeo = (pCutGeo as ITopologicalOperator).Intersect(pNewGeo,
esriGeometryDimension.esriGeometry2Dimension);
pNewFea =
Library.Feature.CreateNewFeature(_App.MapEngine.CurrentFeatureLayer,
pBufGeo, pFea);
if (pNewFea != null)
_App.MapEngine.Map.SelectFeature(_App.MapEngine.CurrentFeatureLayer,
pNewFea);
Library.Geometry.FlashGeometry(pDisp, pBufGeo, 1);
bFlag = true;
bCutHappnend = true;
(_App.FocusMap as
IViewRefresh).PartialRefreshShape((esriViewDrawPhase)65535, null,
pBufGeo, 5);
//(_App.FocusMap as
IViewRefresh).PartialRefreshShape((esriViewDrawPhase.esriViewGeography
| esriViewDrawPhase.esriViewGeoSelection |
esriViewDrawPhase.esriViewBackground |
esriViewDrawPhase.esriViewForeground), pNewFea, pBufGeo, 5);
currentExteriorRing = exteriorRingsEnum.Next() as IRing;
//counter++;
}
exteriorRings = (pRGeo as
IPolygon4).ExteriorRingBag;
//获取Right所有的ExteriorRing
exteriorRingsEnum = exteriorRings as IEnumGeometry;
currentExteriorRing = exteriorRingsEnum.Next() as
IRing; //取一个外环
while (currentExteriorRing !=
null) //处理外环
pNewGeo =
Library.Geometry.CreatePolygonFromRing(currentExteriorRing);
pBufGeo = (pCutGeo as ITopologicalOperator).Intersect(pNewGeo,
esriGeometryDimension.esriGeometry2Dimension);
pNewFea =
Library.Feature.CreateNewFeature(_App.MapEngine.CurrentFeatureLayer,
pBufGeo, pFea);
if (pNewFea != null)
_App.MapEngine.Map.SelectFeature(_App.MapEngine.CurrentFeatureLayer,
pNewFea);
Library.Geometry.FlashGeometry(pDisp, pBufGeo, 1);
bFlag = true;
bCutHappnend = true;
(_App.FocusMap as
IViewRefresh).PartialRefreshShape((esriViewDrawPhase)65535, null,
pBufGeo, 5);
//(_App.FocusMap as
IViewRefresh).PartialRefreshShape((esriViewDrawPhase.esriViewGeography
| esriViewDrawPhase.esriViewGeoSelection |
esriViewDrawPhase.esriViewBackground |
esriViewDrawPhase.esriViewForeground), pNewFea, pBufGeo, 5);
currentExteriorRing = exteriorRingsEnum.Next() as IRing;
}//if (pType == esriGeometryType.esriGeometryPolygon)
else if (pType == esriGeometryType.esriGeometryPolyline)
dLen = (pLGeo as IPolyline).Length;
if (dLen > 0)
pNewFea =
Library.Feature.CreateNewFeature(_App.MapEngine.CurrentFeatureLayer,
pLGeo, pFea);
if (pNewFea != null)
_App.MapEngine.Map.SelectFeature(_App.MapEngine.CurrentFeatureLayer,
pNewFea);
Library.Geometry.FlashGeometry(pDisp, pLGeo, 1);
bFlag = true;
bCutHappnend = true;
(_App.FocusMap as
IViewRefresh).PartialRefreshShape((esriViewDrawPhase)65535, null,
pBufGeo,
5);
//(_App.FocusMap as
IViewRefresh).PartialRefreshShape((esriViewDrawPhase.esriViewGeography
| esriViewDrawPhase.esriViewGeoSelection |
esriViewDrawPhase.esriViewBackground |
esriViewDrawPhase.esriViewForeground), pNewFea, pBufGeo, 5);
}
dLen = (pRGeo as IPolyline).Length;
if (dLen > 0)
pNewFea =
Library.Feature.CreateNewFeature(_App.MapEngine.CurrentFeatureLayer,
pRGeo, pFea);
if (pNewFea != null)
_App.FocusMap.SelectFeature(_App.MapEngine.CurrentFeatureLayer,
pNewFea);
Library.Geometry.FlashGeometry(pDisp, pRGeo, 1);
bFlag = true;
bCutHappnend = true;
(_App.FocusMap as
IViewRefresh).PartialRefreshShape((esriViewDrawPhase)65535, null,
pBufGeo,
5);
//(_App.FocusMap as
IViewRefresh).PartialRefreshShape((esriViewDrawPhase.esriViewGeography
| esriViewDrawPhase.esriViewGeoSelection |
esriViewDrawPhase.esriViewBackground |
esriViewDrawPhase.esriViewForeground), pNewFea, pBufGeo, 5);
}
}//else if (pType == esriGeometryType.esriGeometryPolyLine)
if (bFlag)
try
pFea.Delete();
catch (Exception ex)
Library.Common.AxMessageBox.ShowError(ex.Message.ToString());
}
pFea = (pCur as IFeatureCursor).NextFeature();
}//while
finally
if (!bCutHappnend)
//未分割任何多边形要素
_App.MapEngine.AbortOperation();
else
_App.MapEngine.StopOperation("分割要素");
//_App.ActiveView.Refresh();
}
}
至于切割图形的代码逻辑,这里就不详细介绍了,有兴趣的朋友可以自己研究代码。需要注意的是,由于C#不提供动态数组,所以我们在获取某个图形的外环的时候,不能用数组去获取,而ArcEngine显然考虑到了C#没有提供动态数组的问题,所以利用IPolygon4这个接口,可以获取几何对象的外环,类型为:IGeometryBag。
此外,public void OnFinishSketch(esriGeometry.IGeometry
SketchGeometry) 这个过程由草图工具进行调用,草图工具将当前绘制的Geometry对象传递给编辑任务的OnFinishSketch方法,来完成编辑任务的响应过程。其他类似的编辑任务,如
Create New Feature、Auto Complete Polygon 都可以在编辑任务中来完成。