Exemplo n.º 1
0
        public override void OnMouseDown(int Button, int Shift, int X, int Y)
        {
            m_ActiveView = m_hookHelper.ActiveView;
            m_Map        = m_hookHelper.FocusMap;
            IScreenDisplay    pScreenDisplay = m_ActiveView.ScreenDisplay;
            IRubberBand       pRubberCircle  = new RubberCircleClass();
            ISimpleFillSymbol pFillSymbol    = new SimpleFillSymbolClass();

            pFillSymbol.Color = getRGB(255, 255, 0);
            IGeometry pCircle = pRubberCircle.TrackNew(pScreenDisplay, (ISymbol)pFillSymbol) as IGeometry;

            IConstructCircularArc pConstructArc   = pCircle as IConstructCircularArc;
            IPolygon           pPolygon           = new PolygonClass();
            ISegmentCollection pSegmentCollection = pPolygon as ISegmentCollection;
            ISegment           pSegment           = pConstructArc as ISegment;
            object             missing            = Type.Missing;

            pSegmentCollection.AddSegment(pSegment, ref missing, ref missing);
            pFillSymbol.Style = esriSimpleFillStyle.esriSFSDiagonalCross;
            pFillSymbol.Color = getRGB(255, 0, 0);
            IFillShapeElement pPolygonEle = new PolygonElementClass();

            pPolygonEle.Symbol = pFillSymbol;
            IElement pEle = pPolygonEle as IElement;

            pEle.Geometry = pPolygon;
            IGraphicsContainer pGraphicsContainer = m_Map as IGraphicsContainer;

            pGraphicsContainer.AddElement(pEle, 0);
            m_ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
        }
Exemplo n.º 2
0
        private IPolygon polylinetoPolygon(IPolyline pPolyline)
        {
            IPointCollection pPtC;

            ESRI.ArcGIS.Geometry.IPoint pPt0, pPtn;
            ESRI.ArcGIS.Geometry.ILine  pSeg = new LineClass();

            IPolygon           polygon           = new PolygonClass();
            ISegmentCollection segmentCollection = (ISegmentCollection)pPolyline;
            int segmentCount = segmentCollection.SegmentCount;
            ISegmentCollection segmentCollection2 = (ISegmentCollection)polygon;
            object             value  = Missing.Value;
            object             value2 = Missing.Value;

            for (int i = 0; i < segmentCount; i++)
            {
                segmentCollection2.AddSegment(segmentCollection.get_Segment(i), ref value, ref value2);
            }
            if (!pPolyline.IsClosed)
            {
                pPtC            = pPolyline as IPointCollection;
                pPt0            = pPtC.get_Point(0);
                polygon.ToPoint = pPt0;
                //pPtn = pPtC.get_Point(pPtC.PointCount - 1);
                //pSeg.PutCoords(pPtn, pPt0);
                //segmentCollection2.AddSegment((ISegment)pSeg, ref value, ref value2);
            }

            polygon.SimplifyPreserveFromTo();
            return(polygon);
        }
Exemplo n.º 3
0
 //根据线的方向获取其更新的位置
 private void GetFromPointMovepointChangeLocation(IPolyline line, double distance, ref IPoint point, ref IPolyline retureline)
 {
     try
     {
         IPolyline[] pLines     = new IPolyline[2];
         IPolyline   pSplitLine = new PolylineClass();
         pSplitLine = line;
         IPolyline StarttoPointLine = new PolylineClass();
         IPolyline EndtoPointLine   = new PolylineClass();
         bool      splithappened;
         int       partindex, segmentindex;
         object    pObject = Type.Missing;
         pSplitLine.SplitAtDistance(distance, false, false, out splithappened, out partindex, out segmentindex);
         ISegmentCollection lineSegCol  = pSplitLine as ISegmentCollection;
         ISegmentCollection startSegCol = StarttoPointLine as ISegmentCollection;
         ISegmentCollection endSegCol   = EndtoPointLine as ISegmentCollection;
         for (int i = 0; i < segmentindex; i++)
         {
             startSegCol.AddSegment(lineSegCol.get_Segment(i), ref pObject, ref pObject);
         }
         for (int j = segmentindex; j < lineSegCol.SegmentCount; j++)
         {
             endSegCol.AddSegment(lineSegCol.get_Segment(j), ref pObject, ref pObject);
         }
         pLines[0]  = endSegCol as IPolyline;
         pLines[1]  = startSegCol as IPolyline;
         point      = new PointClass();
         point      = pLines[0].FromPoint;
         retureline = pLines[0];
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message + "/n" + ex.ToString(), "异常");
     }
 }
Exemplo n.º 4
0
 //根据第一应急处置空间位置点,将即将污染的河流切割成两段
 public IPolyline GetPointSplitAtPoint(IPolyline InputLine, IPoint point)
 {
     try
     {
         IPolyline[] pLines     = new IPolyline[2];
         IPolyline   pSplitLine = new PolylineClass();
         pSplitLine = InputLine;
         IPolyline StarttoPointLine = new PolylineClass();
         IPolyline EndtoPointLine = new PolylineClass();
         bool      projectOnto = true, createPart = false;
         bool      SplitHappened;
         int       partindex, segmentindex;
         object    pObject = Type.Missing;
         pSplitLine.SplitAtPoint(point, projectOnto, createPart, out SplitHappened, out partindex, out segmentindex);
         ISegmentCollection lineSegCol  = pSplitLine as ISegmentCollection;
         ISegmentCollection startSegCol = StarttoPointLine as ISegmentCollection;
         ISegmentCollection endSegCol   = EndtoPointLine as ISegmentCollection;
         for (int i = 0; i < segmentindex; i++)
         {
             startSegCol.AddSegment(lineSegCol.get_Segment(i), ref pObject, ref pObject);
         }
         for (int j = segmentindex; j < lineSegCol.SegmentCount; j++)
         {
             endSegCol.AddSegment(lineSegCol.get_Segment(j), ref pObject, ref pObject);
         }
         pLines[0] = endSegCol as IPolyline;
         pLines[1] = startSegCol as IPolyline;
         return(pLines[0]);
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message + "\n" + ex.ToString(), "异常");
         return(null);
     }
 }
Exemplo n.º 5
0
        public override void OnMouseDown(int Button, int Shift, int X, int Y)
        {
            // TODO:  Add SelectByCircle.OnMouseDown implementation

            // TODO:  Add selectAddByRectangle.OnMouseDown implementation


            IRubberBand        pRubberCircle      = new RubberCircleClass();
            IGeometry          pCircle            = pRubberCircle.TrackNew(m_hookHelper.ActiveView.ScreenDisplay, null) as IGeometry;
            IPolygon           pPolygon           = new PolygonClass();                //空的多边形
            ISegmentCollection pSegmentCollection = pPolygon as ISegmentCollection;    //段集合
            ISegment           pSegment           = pCircle as ISegment;               //将圆赋值给段
            object             missing            = Type.Missing;                      //显示默认值

            pSegmentCollection.AddSegment(pSegment, ref missing, ref missing);


            ISpatialFilter ipSpatialFilter = new SpatialFilterClass();


            ipSpatialFilter.Geometry   = pPolygon as IGeometry;
            ipSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            IFeatureSelection ipFeatSelect = m_hookHelper.FocusMap.get_Layer(1) as IFeatureSelection;

            ipFeatSelect.Clear();
            ipFeatSelect.SelectFeatures(ipSpatialFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
            ipFeatSelect.SelectionSet.Refresh();
            m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);

            ICursor cur = null;

            ipFeatSelect.SelectionSet.Search(null, true, out cur);
            IFeature      feature = cur.NextRow() as IFeature;
            IFeatureLayer fl      = m_hookHelper.FocusMap.get_Layer(0) as IFeatureLayer;

            while (feature != null)
            {
                ITopologicalOperator to   = feature.Shape as ITopologicalOperator;
                IPolygon             poly = to.Buffer(0.01) as IPolygon;


                IFeature polyFeature = fl.FeatureClass.CreateFeature();
                polyFeature.Shape = poly;
                feature           = cur.NextRow() as IFeature;
                polyFeature.Store();
            }

            m_hookHelper.ActiveView.Refresh();
        }
Exemplo n.º 6
0
        /// <summary>
        /// Geometry(Polygon)转Polyline
        /// </summary>
        /// <param name="pGeometry">传入的Polygon多边形</param>
        /// <returns>转换后的多段线</returns>
        public static IPolyline PolygonToPolyline(IGeometry pGeometry)
        {
            if (null == pGeometry)
            {
                return(null);
            }
            IPolyline          aTempPolyline           = new PolylineClass();
            ISegmentCollection aTempGeometryCollection = aTempPolyline as ISegmentCollection;
            var pSegmentCollection = pGeometry as ISegmentCollection;

            for (int i = 0; i < pSegmentCollection.SegmentCount; i++)
            {
                aTempGeometryCollection.AddSegment(pSegmentCollection.Segment[i]);
            }
            return(aTempGeometryCollection as IPolyline);
        }
Exemplo n.º 7
0
        private void QueryBoundsFromGeom(int hDC, ref IDisplayTransformation transform, ref IPolygon boundary,
                                         ref IPoint point)
        {
            double map  = 0;
            double num  = 0;
            double map1 = 0;

            num = this.PointsToMap(transform, this.m_dSize);
            if (this.m_dXOffset != 0)
            {
                map = this.PointsToMap(transform, this.m_dXOffset);
            }
            if (this.m_dYOffset != 0)
            {
                map1 = this.PointsToMap(transform, this.m_dYOffset);
            }
            point.PutCoords(point.X + map, point.Y + map1);
            this.SetupDeviceRatio(hDC, transform);
            IPointCollection   pointCollection   = null;
            ISegmentCollection segmentCollection = null;
            double             num1 = 0;
            double             num2 = 0;

            pointCollection   = (IPointCollection)boundary;
            segmentCollection = (ISegmentCollection)boundary;
            num2 = num / 2;
            num1 = Math.Sqrt(num2 * num2 / 2);
            object value = Missing.Value;

            pointCollection.AddPoint(Utility.CreatePoint(point.X + num1, point.Y - num1), ref value, ref value);
            pointCollection.AddPoint(Utility.CreatePoint(point.X - num1, point.Y - num1), ref value, ref value);
            pointCollection.AddPoint(Utility.CreatePoint(point.X - num1, point.Y + num1), ref value, ref value);
            IPoint point1 = pointCollection.Point[0];

            segmentCollection.AddSegment((ISegment)Utility.CreateCircArc(point, pointCollection.Point[2], ref point1),
                                         ref value, ref value);
            ITransform2D transform2D = null;

            if (this.m_dAngle + this.m_dMapRotation != 0)
            {
                transform2D = boundary as ITransform2D;
                transform2D.Rotate(point, Utility.Radians(this.m_dAngle + this.m_dMapRotation));
            }
        }
        /// <summary>
        /// Convert a polyline feature to a polygon
        /// </summary>
        /// <param name="geom">IGeometry</param>
        /// <returns>IPolygon</returns>
        private IPolygon PolylineToPolygon(IGeometry geom)
        {
            //Build a polygon segment-by-segment.
            IPolygon polygon  = new PolygonClass();
            Polyline polyLine = geom as Polyline;

            ISegmentCollection polygonSegs  = polygon as ISegmentCollection;
            ISegmentCollection polylineSegs = polyLine as ISegmentCollection;

            for (int i = 0; i < polylineSegs.SegmentCount; i++)
            {
                ISegment seg = polylineSegs.Segment[i];
                polygonSegs.AddSegment(seg);
            }

            polygon.SimplifyPreserveFromTo();

            return(polygon);
        }
Exemplo n.º 9
0
        private void CreateFeature(IGeometry pGeom)
        {
            IWorkspaceEdit        pWorkspaceEdit  = GetWorkspaceEdit();
            IFeatureLayer         pFeatureLayer   = (IFeatureLayer)m_pCurrentLayer;
            IFeatureClass         pFeatureClass   = pFeatureLayer.FeatureClass;
            IConstructCircularArc pConstructArc   = pGeom as IConstructCircularArc;
            IPolygon           pPolygon           = new PolygonClass();
            ISegmentCollection pSegmentCollection = pPolygon as ISegmentCollection;
            ISegment           pSegment           = pConstructArc as ISegment;
            object             missing            = Type.Missing;

            pSegmentCollection.AddSegment(pSegment, ref missing, ref missing);
            pWorkspaceEdit.StartEditOperation();
            IFeature pFeature = pFeatureClass.CreateFeature();

            pFeature.Shape = pPolygon;

            pFeature.Store();
            pWorkspaceEdit.StopEditOperation();
            m_ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, m_pCurrentLayer, pGeom.Envelope);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Converts the ICircularArc to polygon.
        /// </summary>
        /// <param name="circularArc">The circulararc.</param>
        /// <returns>IPolygon.</returns>
        public static IPolygon ConvertCircularArcToPolygon(ICircularArc circularArc)
        {
            ISegmentCollection segmentCollection = new RingClass();
            ISegmentCollection arg_2B_0          = segmentCollection;
            ISegment           arg_2B_1          = circularArc as ISegment;
            object             value             = Missing.Value;
            object             value2            = Missing.Value;

            arg_2B_0.AddSegment(arg_2B_1, ref value, ref value2);
            IRing ring = segmentCollection as IRing;

            ring.Close();
            IGeometryCollection geometryCollection = new PolygonClass();
            IGeometryCollection arg_5D_0           = geometryCollection;
            IGeometry           arg_5D_1           = ring;

            value  = Missing.Value;
            value2 = Missing.Value;
            arg_5D_0.AddGeometry(arg_5D_1, ref value, ref value2);
            return(geometryCollection as IPolygon);
        }
Exemplo n.º 11
0
        private void CreateFeature(IGeometry pGeom)
        {
            if (pGeom == null)
            {
                return;
            }
            if (m_pCurrentLayer == null)
            {
                return;
            }

            // Create the feature
            IWorkspaceEdit pWorkspaceEdit = GetWorkspaceEdit();
            IFeatureLayer  pFeatureLayer  = (IFeatureLayer)m_pCurrentLayer;
            IFeatureClass  pFeatureClass  = pFeatureLayer.FeatureClass;

            IConstructCircularArc pConstructArc   = pGeom as IConstructCircularArc;
            IPolygon           pPolygon           = new PolygonClass();
            ISegmentCollection pSegmentCollection = pPolygon as ISegmentCollection;
            ISegment           pSegment           = pConstructArc as ISegment;
            object             missing            = Type.Missing;

            pSegmentCollection.AddSegment(pSegment, ref missing, ref missing);

            pWorkspaceEdit.StartEditOperation();
            IFeature pFeature = pFeatureClass.CreateFeature();

            try
            {
                pFeature.Shape = pPolygon;
            }
            catch (Exception ex)
            {
                MessageBox.Show("创建要素", ex.Message);
            }
            pFeature.Store();
            pWorkspaceEdit.StopEditOperation();

            m_ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, m_pCurrentLayer, pGeom.Envelope);
        }
Exemplo n.º 12
0
        //获取将输入点最近点,该线段分割成两段
        public static IPolyline[] GetSubLine(IPoint point, IFeature pFeature)
        {
            try
            {
                IPolyline   pLine            = pFeature.Shape as IPolyline;
                IPolyline[] pLines           = new IPolyline[2];
                IPolyline   StarttoPointLine = new PolylineClass();
                IPolyline   EndtoPointLine   = new PolylineClass();
                bool        splithappened;
                int         partindex, segmentindex;
                object      pObject = Type.Missing;
                //IPoint IPoint = GetNearestPoint(point);
                pLine.SplitAtPoint(point, false, false, out splithappened, out partindex, out segmentindex);
                ISegmentCollection lineSegCol = (ISegmentCollection)pLine;
                ISegmentCollection newSegCol  = (ISegmentCollection)StarttoPointLine;
                ISegmentCollection endSegCol  = EndtoPointLine as ISegmentCollection;
                for (int i = 0; i < segmentindex; i++)
                {
                    newSegCol.AddSegment(lineSegCol.get_Segment(i), ref pObject, ref pObject);
                }
                for (int j = segmentindex; j < lineSegCol.SegmentCount; j++)
                {
                    endSegCol.AddSegment(lineSegCol.get_Segment(j), ref pObject, ref pObject);
                }

                lineSegCol.RemoveSegments(0, segmentindex, true);
                pLines[0] = newSegCol as IPolyline;
                pLines[1] = endSegCol as IPolyline;
                return(pLines);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "异常");
                return(null);
            }
        }
Exemplo n.º 13
0
 //根据距离切割线段,获取切割的点和切割后尾段
 public void GetPointSplitAtDistance(IPolyline InputLine, double distance, ref IPolyline retureLine, ref IPoint returePoint)
 {
     try
     {
         IPolyline[] pLines     = new IPolyline[2];
         IPolyline   pSplitLine = new PolylineClass();
         pSplitLine = InputLine;
         IPolyline StarttoPointLine = new PolylineClass();
         IPolyline EndtoPointLine   = new PolylineClass();
         bool      splithappened;
         int       partindex, segmentindex;
         object    pObject = Type.Missing;
         pSplitLine.SplitAtDistance(distance, false, false, out splithappened, out partindex, out segmentindex);
         ISegmentCollection lineSegCol  = pSplitLine as ISegmentCollection;
         ISegmentCollection startSegCol = StarttoPointLine as ISegmentCollection;
         ISegmentCollection endSegCol   = EndtoPointLine as ISegmentCollection;
         for (int i = 0; i < segmentindex; i++)
         {
             startSegCol.AddSegment(lineSegCol.get_Segment(i), ref pObject, ref pObject);
         }
         for (int j = segmentindex; j < lineSegCol.SegmentCount; j++)
         {
             endSegCol.AddSegment(lineSegCol.get_Segment(j), ref pObject, ref pObject);
         }
         pLines[0]   = endSegCol as IPolyline;
         pLines[1]   = startSegCol as IPolyline;
         returePoint = new PointClass();
         bool asRatio = false;
         pLines[1].QueryPoint(esriSegmentExtension.esriNoExtension, pLines[1].Length / 2, asRatio, returePoint);
         retureLine = pLines[0];
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message + "\n" + ex.ToString(), "异常");
     }
 }
Exemplo n.º 14
0
        public override void OnMouseDown(int Button, int Shift, int X, int Y)
        {
            // TODO:  Add ToolCreateCircle.OnMouseDown implementation
            if ((m_pMapCtl = ClsGlobal.GetMapControl(m_hookHelper)) == null)
            {
                return;
            }
            IPoint pPoint = m_pMapCtl.ToMapPoint(X, Y);

            if (Button == 1)
            {
                if (m_NewCircleFeedback == null)
                {
                    m_NewCircleFeedback         = new NewCircleFeedbackClass();
                    m_NewCircleFeedback.Display = m_pMapCtl.ActiveView.ScreenDisplay;

                    m_NewCircleFeedback.Start(pPoint);
                    m_CenterPoint = pPoint;
                }
                else
                {
                    try
                    {
                        object       Miss = Type.Missing;
                        ICircularArc pArc = m_NewCircleFeedback.Stop();
                        //IGeometry geometry = new PolygonClass();
                        //geometry = m_pMapCtl.TrackCircle();
                        IPolygon           pPolygon = new PolygonClass();
                        ISegment           pArcC    = pArc as ISegment;
                        ISegmentCollection pArcP    = pPolygon as ISegmentCollection;
                        pArcP.AddSegment(pArcC, ref Miss, ref Miss);
                        pPolygon.Close();
                        IFeature pFeature = m_FLayer.FeatureClass.CreateFeature();
                        pFeature.Shape = pPolygon;
                        pFeature.Store();
                        m_pMapCtl.Refresh();
                        m_NewCircleFeedback = null;
                    }
                    catch (System.Exception ex)
                    {
                    }
                }
            }
            if (Button == 2)
            {
                double                radius        = Math.Sqrt((pPoint.X - m_CenterPoint.X) * (pPoint.X - m_CenterPoint.X) + (pPoint.Y - m_CenterPoint.Y) * (pPoint.Y - m_CenterPoint.Y));
                FrmDrawCircle         frm           = new FrmDrawCircle(radius);
                IConstructCircularArc pArcConstruct = null;
                if (m_NewCircleFeedback == null)
                {
                    return;
                }

                if (frm.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        pArcConstruct = new CircularArcClass();
                        pArcConstruct.ConstructCircle(m_CenterPoint, frm.m_radius, false);
                        if (pArcConstruct != null)
                        {
                            IPolygon           pPolygon = new PolygonClass();
                            ISegment           pArcC    = pArcConstruct as ISegment;
                            ISegmentCollection pArcP    = pPolygon as ISegmentCollection;
                            pArcP.AddSegment(pArcC);
                            pPolygon.Close();
                            IFeature pFeature = m_FLayer.FeatureClass.CreateFeature();
                            pFeature.Shape = pPolygon;
                            pFeature.Store();
                            m_pMapCtl.Refresh();
                            m_NewCircleFeedback.Stop();
                            m_NewCircleFeedback = null;
                        }
                    }
                    catch (System.Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                        if (m_NewCircleFeedback != null)
                        {
                            m_NewCircleFeedback.Stop();
                        }
                        m_NewCircleFeedback = null;
                    }
                }
            }
        }
Exemplo n.º 15
0
        private void btnAddFeature_Click(object sender, EventArgs e)
        {
            IPoint pPoint1 = new PointClass();

            pPoint1.PutCoords(82.1935, 21.5459);

            IPoint pPoint2 = new PointClass();

            pPoint2.PutCoords(89.0913, 21.6609);

            IPoint pPoint3 = new PointClass();

            pPoint3.PutCoords(88.9763, 15.6828);

            IPoint pPoint4 = new PointClass();

            pPoint4.PutCoords(79.7793, 15.5679);

            // 创建一个环
            IRing pRing = new RingClass();
            ISegmentCollection pSegmentCollection = pRing as ISegmentCollection;

            object Missing1 = Type.Missing;
            object Missing2 = Type.Missing;

            ILine pLine = new LineClass();

            pLine.PutCoords(pPoint1, pPoint2);
            pSegmentCollection.AddSegment(pLine as ISegment, ref Missing1, ref Missing2);

            pLine = new LineClass();
            pLine.PutCoords(pPoint2, pPoint3);
            pSegmentCollection.AddSegment(pLine as ISegment, ref Missing1, ref Missing2);

            pLine = new LineClass();
            pLine.PutCoords(pPoint3, pPoint4);
            pSegmentCollection.AddSegment(pLine as ISegment, ref Missing1, ref Missing2);

            pLine = new LineClass();
            pLine.PutCoords(pPoint4, pPoint1);
            pSegmentCollection.AddSegment(pLine as ISegment, ref Missing1, ref Missing2);

            pRing.Close();

            // 创建多边形
            IPolygon            pPolygon            = new PolygonClass();
            IGeometryCollection pGeometryCollection = pPolygon as IGeometryCollection;

            pGeometryCollection.AddGeometry(pRing, ref Missing1, ref Missing2);

            // 显示多边形
            ISimpleFillSymbol pSimpleFillSymbol = new SimpleFillSymbolClass();
            IRgbColor         pColor            = new RgbColorClass();

            pColor.Red   = 255;
            pColor.Blue  = 0;
            pColor.Green = 0;

            pSimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSDiagonalCross;
            pSimpleFillSymbol.Color = pColor;

            IFillShapeElement pFillShapeElement = new PolygonElementClass();

            pFillShapeElement.Symbol = pSimpleFillSymbol;

            IElement pElement = pFillShapeElement as IElement;

            pElement.Geometry = pPolygon as IGeometry;

            IGraphicsContainer pGraphicsContainer = MainMap.Map as IGraphicsContainer;

            pGraphicsContainer.AddElement(pElement, 0);
            MainMap.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
        }
Exemplo n.º 16
0
        private IPolyline GetNonLinearSubpart(int startSegmentIndex, double startFraction,
                                              int endSegmentIndex, double endFraction)
        {
            var subpart = new PolylineClass();
            IPointCollection4  points = subpart;
            ISegmentCollection segs   = subpart;

            subpart.SpatialReference = SpatialReference;

            bool hasNonLinearParts = false;

            object         missing = Type.Missing;
            SegmentProxy   segProxy;
            AoSegmentProxy aoSegProxy;

            #region startSegment

            var currentWksPoints = new List <WKSPointZ>();
            if (_nonLinearSegments.TryGetValue(startSegmentIndex, out aoSegProxy))
            {
                hasNonLinearParts = true;
                ISegment seg = aoSegProxy.InnerSegment;
                ICurve   part;

                double end = 1;
                if (endSegmentIndex == startSegmentIndex)
                {
                    end = endFraction;
                }

                seg.GetSubcurve(startFraction, end, true, out part);

                segs.AddSegment((ISegment)part, ref missing, ref missing);
            }
            else
            {
                segProxy = GetSegment(startSegmentIndex);
                IPnt p = segProxy.GetPointAt(startFraction, as3D: true);
                currentWksPoints.Add(QaGeometryUtils.GetWksPoint(p));
            }

            #endregion

            #region segments

            for (int i = startSegmentIndex + 1; i < endSegmentIndex; i++)
            {
                if (_nonLinearSegments.TryGetValue(i, out aoSegProxy))
                {
                    hasNonLinearParts = true;

                    if (currentWksPoints.Count > 0)
                    {
                        currentWksPoints.Add(_points[i]);
                        WKSPointZ[] add = currentWksPoints.ToArray();
                        GeometryUtils.AddWKSPointZs(points, add);
                        currentWksPoints.Clear();
                    }

                    ISegment seg = GeometryFactory.Clone(aoSegProxy.InnerSegment);
                    segs.AddSegment(seg, ref missing, ref missing);
                }
                else
                {
                    currentWksPoints.Add(_points[i]);
                }
            }

            #endregion

            #region endsegment

            if (startSegmentIndex == endSegmentIndex)
            {
                if (currentWksPoints.Count > 0)
                {
                    segProxy = GetSegment(endSegmentIndex);
                    IPnt p = segProxy.GetPointAt(endFraction, as3D: true);
                    currentWksPoints.Add(QaGeometryUtils.GetWksPoint(p));
                    WKSPointZ[] add = currentWksPoints.ToArray();
                    GeometryUtils.AddWKSPointZs(points, add);
                }
            }
            else
            {
                if (_nonLinearSegments.TryGetValue(endSegmentIndex, out aoSegProxy))
                {
                    hasNonLinearParts = false;
                    if (currentWksPoints.Count > 0)
                    {
                        currentWksPoints.Add(_points[endSegmentIndex]);
                        WKSPointZ[] add = currentWksPoints.ToArray();
                        GeometryUtils.AddWKSPointZs(points, add);
                        currentWksPoints.Clear();
                    }

                    ISegment seg = aoSegProxy.InnerSegment;
                    ICurve   part;
                    seg.GetSubcurve(0, endFraction, true, out part);
                    segs.AddSegment((ISegment)part, ref missing, ref missing);
                }
                else
                {
                    currentWksPoints.Add(_points[endSegmentIndex]);
                    segProxy = GetSegment(endSegmentIndex);

                    IPnt p = segProxy.GetPointAt(endFraction, as3D: true);
                    currentWksPoints.Add(QaGeometryUtils.GetWksPoint(p));

                    WKSPointZ[] add = currentWksPoints.ToArray();
                    GeometryUtils.AddWKSPointZs(points, add);
                }
            }

            #endregion

            if (hasNonLinearParts)
            {
                var topoOp = (ITopologicalOperator2)subpart;
                topoOp.IsKnownSimple_2 = false;
                topoOp.Simplify();
            }

            return(subpart);
        }