private void DWIntersect(CPolyline pBSCpl, ref List <CPoint> cptlt, double dblIgnorableDis)
        {
            IPointCollection4 pCol = new PolylineClass();

            for (int i = 0; i < cptlt.Count; i++)
            {
                cptlt[i].SetPoint();
                pCol.AddPoint(cptlt[i].pPoint);
            }
            IPolyline5 ipl = pCol as IPolyline5;

            pBSCpl.SetPolyline();
            IRelationalOperator pRel = pBSCpl.pPolyline as IRelationalOperator;
            bool isCrosses           = pRel.Crosses(ipl);

            if (isCrosses == true)
            {
                ITopologicalOperator pTop          = pBSCpl.pPolyline as ITopologicalOperator;
                IGeometry            pGeoIntersect = pTop.Intersect(ipl, esriGeometryDimension.esriGeometry0Dimension);
                IPointCollection4    pColIntersect = pGeoIntersect as IPointCollection4;

                double dblMaxDis = 0;
                for (int j = 0; j < pColIntersect.PointCount; j++)
                {
                    double dblDis = CGeoFunc.CalDistanceFromStartPoint(ipl, pColIntersect.get_Point(j), false);
                    if (dblDis > dblMaxDis)
                    {
                        dblMaxDis = dblDis;
                    }
                }

                ICurve pSubCurve;
                ipl.GetSubcurve(dblMaxDis, ipl.Length, false, out pSubCurve);
                //IPolyline5 Cutipl = pSubCurve as IPolyline5;
                IPointCollection4 iplCutCol = pSubCurve as IPointCollection4;

                //the new first segment
                IPointCollection4 pSegCol = new PolylineClass();
                pSegCol.AddPoint(ipl.FromPoint, _Missing, _Missing);
                pSegCol.AddPoint(iplCutCol.get_Point(1), _Missing, _Missing);
                IPolyline5 seg = pSegCol as IPolyline5;
                bool       isCrossesSeg;

                int intIndex = 0;
                while (intIndex < iplCutCol.PointCount - 1)
                {
                    intIndex++;
                    pSegCol.UpdatePoint(1, iplCutCol.get_Point(intIndex));
                    isCrossesSeg = pRel.Crosses(seg);
                    if (isCrossesSeg == false)
                    {
                        iplCutCol.RemovePoints(1, intIndex - 1);
                        iplCutCol.UpdatePoint(0, ipl.FromPoint);
                        break;
                    }
                    if (seg.Length >= dblIgnorableDis)
                    {
                        double dblOriginalIntersectionDis  = CGeoFunc.CalDistanceFromStartPoint(pBSCpl.pPolyline, pCol.get_Point(0), false);
                        double dblRealisticIntersectionDis = CGeoFunc.CalDistanceFromStartPoint(pBSCpl.pPolyline, iplCutCol.get_Point(0), false);

                        IPointCollection4 pColBSCpl = pBSCpl.pPolyline as IPointCollection4;
                        double            dblSumDis = 0;
                        for (int i = 0; i < pColBSCpl.PointCount - 1; i++)
                        {
                            double dblDis = CGeoFunc.CalDis(pColBSCpl.get_Point(i), pColBSCpl.get_Point(i + 1));
                            dblSumDis += dblDis;
                            if (dblSumDis >= dblRealisticIntersectionDis)
                            {
                                double dblDisPre   = Math.Abs(dblSumDis - dblDis - dblOriginalIntersectionDis);
                                double dblDisNext  = Math.Abs(dblSumDis - dblOriginalIntersectionDis);
                                IPoint intersectpt = new PointClass();
                                if (dblDisPre <= dblDisNext)
                                {
                                    intersectpt = pColBSCpl.get_Point(i);
                                }
                                else
                                {
                                    intersectpt = pColBSCpl.get_Point(i + 1);
                                }
                                iplCutCol.UpdatePoint(0, intersectpt);
                                break;
                            }
                        }
                        break;
                    }
                }
                cptlt = CHelpFunc.GetCptEbByICol(iplCutCol).ToList();
            }
        }
        public override void OnClick()
        {
            try
            {
                //setup a file stream and a stream writer to write out the addresses that do not have a nearby street or a street out of range
                string path = @"C:\temp\DeleteDupVerts" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm") + ".txt";
                System.IO.FileStream fileStream   = new System.IO.FileStream(path, FileMode.Create);
                StreamWriter         streamWriter = new StreamWriter(fileStream);
                streamWriter.WriteLine("UniqueID" + "," + "FeatureOID" + "," + "VertIndex1" + "," + "VertIndex2");
                int  intUniqueID = 0;
                bool updatePreviousPnt;
                int  numberOfVerticesRemovedFromPntCollection;
                int  vertexIndexToRemove;

                // get access to the current arcmap variables
                clsPushSgidStaticClass.GetCurrentMapDocVariables();

                // show the cursor as busy
                System.Windows.Forms.Cursor.Current = Cursors.WaitCursor;

                clsGlobals.pGFlayer     = null;
                clsGlobals.arcFeatLayer = null;
                IFeatureLayer arcFeatureLayerVertPnts = null;
                IFeatureClass arcFeatureClassVertPnts = null;
                //var listOfIndexesToRemove = new List<Int32>();

                // loop through the map's layers and check for the layer with the targeted name
                for (int i = 0; i < clsGlobals.pMap.LayerCount; i++)
                {
                    if (clsGlobals.pMap.Layer[i].Name == "REMOVE_DUP_VERTS")
                    {
                        clsGlobals.pGFlayer     = (IGeoFeatureLayer)clsGlobals.pMap.Layer[i];
                        clsGlobals.arcFeatLayer = (IFeatureLayer)clsGlobals.pMap.Layer[i];
                    }

                    if (clsGlobals.pMap.Layer[i].Name == "VERT_PNTS")
                    {
                        arcFeatureLayerVertPnts = (IFeatureLayer)clsGlobals.pMap.Layer[i];
                        arcFeatureClassVertPnts = arcFeatureLayerVertPnts.FeatureClass;
                    }
                }

                // make sure the user is editing
                //get the editor extension
                UID arcUID = new UID();
                arcUID.Value         = "esriEditor.Editor";
                clsGlobals.arcEditor = clsGlobals.arcApplication.FindExtensionByCLSID(arcUID) as IEditor3;

                // check if editing first
                if (clsGlobals.arcEditor.EditState == ESRI.ArcGIS.Editor.esriEditState.esriStateNotEditing)
                {
                    MessageBox.Show("You must be editing in order to remove duplicate vertices.", "Must Be Editing",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                IDataset       arcDataset       = (IDataset)clsGlobals.arcFeatLayer;
                IWorkspace     arcWorkspace     = arcDataset.Workspace;
                IWorkspaceEdit arcWorkspaceEdit = (IWorkspaceEdit)arcWorkspace;

                // make sure we're editing the correct workspace
                if (!(arcWorkspaceEdit.IsBeingEdited()))
                {
                    MessageBox.Show("You must be editing the REMOVE_DUP_VERTS layer in order to proceed.",
                                    "Must Be Editing", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                // get access to the selected features in the user specified layer
                IDisplayTable arcDisplayTable = (IDisplayTable)clsGlobals.arcFeatLayer;
                ISelectionSet arcSelectionSet = arcDisplayTable.DisplaySelectionSet;

                // make sure there's at least one feature selected in the specified layer
                if (arcSelectionSet.Count == 0)
                {
                    MessageBox.Show(
                        "You must select at least one feature in the REMOVE_DUP_VERTS layer to spatially assign values to.",
                        "No Features are Selected.", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                // confirm the user wants to edit that layer's fields on the selected records
                DialogResult dialogResult =
                    MessageBox.Show(
                        "Would you like to proceed with editing " + arcSelectionSet.Count +
                        " features on the REMOVE_DUP_VERTS Layer, removing non-coincident verticies that are within 1 meter of eachother?",
                        "Confirm Edits", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                if (dialogResult == DialogResult.Yes)
                {
                    // loop through the selected feature remove_dup_verts layer
                    IEnumIDs arcEnumIDs = arcSelectionSet.IDs;
                    int      iD;
                    while ((iD = arcEnumIDs.Next()) != -1)
                    {
                        vertexIndexToRemove = 0;
                        numberOfVerticesRemovedFromPntCollection = 0;

                        clsGlobals.arcFeatureToEditSpatial = clsGlobals.arcFeatLayer.FeatureClass.GetFeature(iD);
                        clsGlobals.arcEditor.StartOperation();

                        // Loop through this features verticies.
                        // Get the feature's geometry.
                        IGeometry arcEdit_geometry = clsGlobals.arcFeatureToEditSpatial.Shape;
                        IPolyline arcEdit_polyline = arcEdit_geometry as IPolyline;

                        // get a point collection
                        IPointCollection4 pointCollection = (IPointCollection4)arcEdit_polyline;
                        IPoint            currPoint       = null;
                        IPoint            previousPoint   = null;

                        // Iterate the point collection array (the first point is the start of the line and last is the end of the line).
                        // I added the numberOfVerticesRemovedFromPntCollection variable in order to preserve the initial point collection iterations (it's needed in order to loop through all the original vertices)
                        for (int i = 0; i < pointCollection.PointCount + numberOfVerticesRemovedFromPntCollection; i++)
                        {
                            // Reset the boolean value.
                            updatePreviousPnt = true;

                            // Reset the number of vertices removed to zero
                            //numberOfVerticesRemovedFromPntCollection = 0;
                            //vertexIndexToRemove = 0;

                            // Get the current point.
                            currPoint = null;
                            // This is the problem as it's setting the current i point, but this should be a reference to the original index
                            //currPoint = pointCollection.get_Point(i);
                            currPoint = pointCollection.get_Point(i - numberOfVerticesRemovedFromPntCollection);
                            //MessageBox.Show("X:" + currPoint.X + " , Y:" + currPoint.Y);

                            // Check if the previous point has been assigned yet (if not, it's the first itteration of this line segment)
                            if (previousPoint != null)
                            {
                                // Check the distance between the currPoint and previousPoint to see if it's less than 1 meter
                                IProximityOperator proximityOperator;
                                IGeometry          currGeometry     = currPoint;
                                IGeometry          previousGeometry = previousPoint;
                                proximityOperator = currGeometry as IProximityOperator;

                                // Check distance to the previous vertex.
                                double distBetweenCurrAndPrevPnt = proximityOperator.ReturnDistance(previousGeometry);

                                // Check if distance is less than 1 meter.
                                if (distBetweenCurrAndPrevPnt <= 3)
                                {
                                    //MessageBox.Show(distance.ToString() + " is less than 1 meter.");

                                    // Check if the the current point intersects any other vertices, before we delete it.
                                    // If it does, then check the current point to see if intersects any other vertices, before we delete it.
                                    ISpatialFilter spatialFilterCurr = new SpatialFilterClass();
                                    spatialFilterCurr.Geometry   = currGeometry;
                                    spatialFilterCurr.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

                                    IFeatureCursor featureCursorCurr = arcFeatureClassVertPnts.Search(spatialFilterCurr, false);
                                    IFeature       featureCurr       = null;
                                    int            vertAtCurrPnt     = 0;

                                    while ((featureCurr = featureCursorCurr.NextFeature()) != null)
                                    {
                                        vertAtCurrPnt = vertAtCurrPnt + 1;
                                    }

                                    // Check if we can delete this vertex
                                    if (vertAtCurrPnt > 1)
                                    {
                                        // There's more than one vertex here at the current vertex/point, so we cant' delete it, check the the previous
                                        // now check the if we can delete the previous point (as we can't delete the current point b/c it is co-incident)
                                        ISpatialFilter spatialFilterPrev = new SpatialFilterClass();
                                        spatialFilterPrev.Geometry   = previousGeometry;
                                        spatialFilterPrev.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

                                        IFeatureCursor featureCursorPrev = arcFeatureClassVertPnts.Search(spatialFilterPrev, false);
                                        IFeature       featurePrev       = null;
                                        int            vertsAtPrevPnt    = 0;

                                        while ((featurePrev = featureCursorPrev.NextFeature()) != null)
                                        {
                                            vertsAtPrevPnt = vertsAtPrevPnt + 1;
                                        }

                                        // Check if we can delete this vertex
                                        if (vertsAtPrevPnt > 1)
                                        {
                                            // can delete this one either, so log it in the text file so we can inspect it manual
                                            intUniqueID = intUniqueID + 1;
                                            streamWriter.WriteLine(intUniqueID + "," + clsGlobals.arcFeatureToEditSpatial.OID + "," + i + "," + Convert.ToString(i - 1));

                                            //MessageBox.Show("Can't Delete either vertex for this 1 meter duplicate.  Help!  Need a human!");
                                        }
                                        else
                                        {
                                            // Delete the previous vertex.

                                            // Add this index to the list of
                                            //listOfIndexesToRemove.Add(i);

                                            vertexIndexToRemove = i - numberOfVerticesRemovedFromPntCollection;

                                            // test replacing the point collection before we do anything with it
                                            //pointCollection.ReplacePointCollection(0,pointCollection.PointCount,pointCollection);
                                            //MessageBox.Show("before remove: " + pointCollection.PointCount);
                                            // Remove the point from the collection.
                                            //pointCollection.RemovePoints(i - 1, 1);
                                            pointCollection.RemovePoints(vertexIndexToRemove - 1, 1);
                                            //MessageBox.Show("after remove: " + pointCollection.PointCount);

                                            // Increment the total number of vertices removed
                                            numberOfVerticesRemovedFromPntCollection =
                                                numberOfVerticesRemovedFromPntCollection + 1;
                                            // reset the point collection, now that the point has been removed
                                            //pointCollection.ReplacePointCollection(i, i - pointCollection.PointCount, pointCollection);

                                            // Replace the features shape with the newly modified point collection.
                                            //clsGlobals.arcFeatureToEditSpatial.Shape = pointCollection as IGeometry;
                                            //clsGlobals.arcFeatureToEditSpatial.Store();
                                        }

                                        // release the feature cursor
                                        System.Runtime.InteropServices.Marshal.ReleaseComObject(featureCursorPrev);
                                    }
                                    else
                                    {
                                        // Delete the current vertex
                                        // Add this index to the list of
                                        //listOfIndexesToRemove.Add(i);

                                        vertexIndexToRemove = i - numberOfVerticesRemovedFromPntCollection;

                                        // test replacing the point collection before we do anything with it
                                        //pointCollection.ReplacePointCollection(0, pointCollection.PointCount, pointCollection);
                                        //MessageBox.Show("before remove: " + pointCollection.PointCount);
                                        // Remove the point from the collection.
                                        //pointCollection.RemovePoints(i, 1);
                                        pointCollection.RemovePoints(vertexIndexToRemove, 1);
                                        //MessageBox.Show("after remove: " + pointCollection.PointCount);

                                        // Increment the total number of vertices removed
                                        numberOfVerticesRemovedFromPntCollection =
                                            numberOfVerticesRemovedFromPntCollection + 1;

                                        // since we are removing this current point, make sure we don't assign it as the previousPoint (in other words keep the active previous point for the next iterattion)
                                        updatePreviousPnt = false;

                                        // reset the point collection, now that the point has been removed
                                        //pointCollection.ReplacePointCollection(i,i- pointCollection.PointCount,pointCollection);

                                        // Replace the features shape with the newly modified point collection.
                                        //clsGlobals.arcFeatureToEditSpatial.Shape = pointCollection as IGeometry;
                                        //clsGlobals.arcFeatureToEditSpatial.Store();
                                    }

                                    // release the feature cursor
                                    System.Runtime.InteropServices.Marshal.ReleaseComObject(featureCursorCurr);
                                }
                            }


                            // Set this current point to the next point, so next time through the iteration we can check the distance between them.
                            if (updatePreviousPnt)
                            {
                                previousPoint = null;
                                previousPoint = currPoint;
                            }

                            //MessageBox.Show("total times though the loop: " + i);
                        }


                        //// Remove the ID'd verticies from this segment
                        //foreach (var index in listOfIndexesToRemove)
                        //{
                        //    // Remove the point from the collection.
                        //    pointCollection.RemovePoints(index, 1);
                        //}

                        // Replace the features shape with the newly modified point collection.
                        clsGlobals.arcFeatureToEditSpatial.Shape = pointCollection as IGeometry;
                        clsGlobals.arcFeatureToEditSpatial.Store();
                        clsGlobals.arcEditor.StopOperation("RemovedDuplicateVertices");
                    }

                    //close the stream writer
                    streamWriter.Close();

                    MessageBox.Show(
                        "Done updating " + arcSelectionSet.Count +
                        " features on the REMOVE_DUP_VERTS Layer, removing non-coincident vertices that were within 1 meter of eachother.  Don't forget to save edits if you want to retain the changes.",
                        "Done!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                else if (dialogResult == DialogResult.No)
                {
                    return;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error Message: " + Environment.NewLine + ex.Message + Environment.NewLine + Environment.NewLine +
                                "Error Source: " + Environment.NewLine + ex.Source + Environment.NewLine + Environment.NewLine +
                                "Error Location:" + Environment.NewLine + ex.StackTrace,
                                "Push Utrans Roads to SGID!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

                clsGlobals.arcEditor.StopOperation("RemovedDuplicateVertices");
            }
        }