AE用線來分割線面(C#2010+AE10.0…

希望指正。

在 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)//如果選擇的線有一些沒有與分割線相交,那麼PointCount0,但是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;

        }

發佈了48 篇原創文章 · 獲贊 18 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章