希望指正。
在 ITools 類中,部分方法如下:
public override void OnMouseDown(int Button, int Shift, int X, int Y)
{
if (Button != 1)
return;
#region……分割面
//根據已選擇的要分割的要素的類型繪製分割線
if (pFeatureLayer.FeatureClass.ShapeType==esriGeometryType.esriGeometryPolygon)
{//分割線的樣式
IScreenDisplay pScreenDisplay = m_hookHelper.ActiveView.ScreenDisplay;
ISimpleLineSymbol pLineSymbol = new SimpleLineSymbolClass();
IRgbColor pRgbColor = new RgbColorClass();
pRgbColor.Red = 255;
pLineSymbol.Color = pRgbColor;
IRubberBand pRubberBand = new RubberLineClass();
IPolyline pPolyline = (IPolyline)pRubberBand.TrackNew(pScreenDisplay, (ISymbol)pLineSymbol);
pScreenDisplay.StartDrawing(pScreenDisplay.hDC, (short)esriScreenCache.esriNoScreenCache);
pScreenDisplay.SetSymbol((ISymbol)pLineSymbol);
pScreenDisplay.DrawPolyline(pPolyline);
pScreenDisplay.FinishDrawing();
//清理將被分割的要素
ITopologicalOperator pTopoOpo;
pTopoOpo = pPolyline as ITopologicalOperator;
pTopoOpo.Simplify();//確保幾何體的拓撲正確
m_engineEditor.StartOperation();
//分割方法
SplitPolygon(pSelectionSet, pPolyline);
ReBackStates();//刷新返回修改工具
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, m_hookHelper.ActiveView.Extent);
}
#endregion
#region……鼠標畫線分割線
//根據分割要素的類型繪製分割線
if (pFeatureLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
{
IScreenDisplay pScreenDisplay = m_hookHelper.ActiveView.ScreenDisplay;
ISimpleLineSymbol pLineSymbol = new SimpleLineSymbolClass();
IRgbColor pRgbColor = new RgbColorClass();
pRgbColor.Red = 255;
pLineSymbol.Color = pRgbColor;
IRubberBand pRubberBand = new RubberLineClass();
IPolyline pPolyline = (IPolyline)pRubberBand.TrackNew(pScreenDisplay, (ISymbol)pLineSymbol);
pScreenDisplay.StartDrawing(pScreenDisplay.hDC, (short)esriScreenCache.esriNoScreenCache);
pScreenDisplay.SetSymbol((ISymbol)pLineSymbol);
pScreenDisplay.DrawPolyline(pPolyline);
pScreenDisplay.FinishDrawing();
m_engineEditor.StartOperation();//開啓編輯
//分割方法
SplitPolyline(pSelectionSet, pPolyline);
ReBackStates();
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, m_hookHelper.ActiveView.Extent);
}
#endregion
m_engineEditor.StopOperation("ControlToolsEditing_CreateNewFeatureTask");
}
//分割面
public void SplitPolygon(ISelectionSet pSelectionSet, IGeometry pGeometry)
{
//使用空間過濾器來獲得將要與線或點進行分割的要素類
IFeatureCursor pFeatCursor;
ICursor pCursor;
ISpatialFilter pSpatialFilter;
pSpatialFilter = new SpatialFilterClass();
pSpatialFilter.Geometry = pGeometry;
if (pGeometry.GeometryType == esriGeometryType.esriGeometryPolyline)//.esriGeometryPoint)
{
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;//空間關係
}
pSelectionSet.Search(pSpatialFilter, true, out pCursor);
pFeatCursor = pCursor as IFeatureCursor;
//清理將被分割的要素
ITopologicalOperator pTopoOpo;
pTopoOpo = pGeometry as ITopologicalOperator;
pTopoOpo.Simplify();//確保幾何體的拓撲正確
IFeature pFeature;
pFeature = pFeatCursor.NextFeature();
if (pFeature == null) return;
while (pFeature != null)
{
IFeatureEdit pFeatureEdit;
pFeatureEdit = pFeature as IFeatureEdit;
ISet pSet;
pSet = pFeatureEdit.Split(pGeometry);//直接用線分割
for (int setCount = 0; setCount < pSet.Count; setCount++)
{
pFeature = pSet.Next() as IFeature;
//featureSelection.SelectionSet.Add(pFeature.OID);
}
pFeature = pFeatCursor.NextFeature();
}
MessageBox.Show("面分割完畢!繼續選擇以分割!");
}
//分割線,線要素不能用線來分割,得用點來。所以要將分割線與被分割線求交叉點
public void SplitPolyline(ISelectionSet pSelectionSet, IGeometry pGeometry)
{
IFeatureClass featureClass=pFeatureLayer.FeatureClass;
IEnumIDs enumIDs = pSelectionSet.IDs;
int id = enumIDs.Next();
while(id!=-1)
{
pFeature = featureClass.GetFeature(id);
IGeometry pGeo = pFeature.ShapeCopy;
//由於在拓撲是需要空間參考一致,所以要將空間參考座標設置一下。
pGeo.SpatialReference = pGeometry.SpatialReference;
ITopologicalOperator pTopoOpo = pGeo as ITopologicalOperator;
//Intersect()方法求出來的是MultiPoint,而不是單點
IPointCollection pPCol = pTopoOpo.Intersect(pGeometry, esriGeometryDimension.esriGeometry0Dimension) as IPointCollection;
pTopoOpo.Simplify();
if (pPCol == null)//如果沒有相交的,那麼點集就爲空。
return;
if (pPCol.PointCount == 0)//如果選擇的線有一些沒有與分割線相交,那麼PointCount爲0,但是0並不是null。
{
id = enumIDs.Next();//那麼就Next(),讓他進入下一個回合吧
continue;
}
IFeatureEdit pFeatureEdit;
pFeatureEdit = pFeature as IFeatureEdit;
ISet pSet;
pSet = pFeatureEdit.Split(pPCol.get_Point(0));
pSet.Reset();
//這一步進入分割大賽,其實分割爲兩個部分,當然要是隻是分割單個要素的話就用不着裏面那一層嵌套循環了。
for (int setCount = 0; setCount < pSet.Count; setCount++)
{
pFeature = pSet.Next() as IFeature;
if (pFeature == null) return;
for (int i = 1; i < pPCol.PointCount; i++)
{
try
{
pFeatureEdit = pFeature as IFeatureEdit;
IPoint pPoint = pPCol.get_Point(i);
pSet = pFeatureEdit.Split(pPoint);//這裏新產生的線要素,可能與下一個交點進行分割,所以要重新獲取以便進行下一次分割
pSet.Reset();
pPCol.RemovePoints(i, 1);//爲了少循環一次,用了一個點就從點集中移除它,因爲兩線相交肯定沒有二心。
break;//打斷,這一步是迫不得已的,因爲懶得去想另一部分。當然這樣的話有個問題:如3點分線應該是4段,但如果這點剛好是中間的點,那麼就會丟掉他前面或者後面的一個分割點,如此的話就變成2點分線爲3段了;而且畫的分割折線與被分割線交點越多丟失的就越多。主要原因是MultiPoint撞到IPointCollection中後順序並不是畫線時候的交叉順序。怎麼辦呢?
}
catch
{
continue;
}
}
}
id = enumIDs.Next();
}
MessageBox.Show("線分割完畢!繼續選擇以分割!");
}
private void ReBackStates()
{
//清空選擇集
ICommand pCommand = new ControlsClearSelectionCommandClass();
pCommand.OnCreate(pMapControl.Object);
pCommand.OnClick();
pCommand = new ControlsEditingEditToolClass();
pCommand.OnCreate(pMapControl.Object);
pMapControl.CurrentTool = pCommand as ITool;
}