Surface layer check graph self-intersection method C#

Method 1: processing based on arcgis engine, because AE-based topology inspection rules only have line self-intersection inspection, so the processing logic here is to traverse the surface elements, and then channel the inner and outer rings of each surface element, and then independently construct line elements, using To check the topology, the code is as follows:

 void topTest()
        {<!-- -->
            string topGdbPath = @"E:\Data\topology.gdb";
            string err = "";
              IWorkspaceFactory pWf = new FileGDBWorkspaceFactoryClass();
            IWorkspace workspace = pWf.OpenFromFile(topGdbPath , 0)
             IFeatureWorkspace pFeatureWorkspace = pWs as IFeatureWorkspace;
            string mes = "";
            IFeatureClass featureClass =pFeatureWorkspace. OpenFeatureClass("SLZY");
            try
            {<!-- -->
                long fCount = featureClass. FeatureCount(null);
                IFeatureCursor cursor = featureClass. Search(null, true);
                IFeature feature = cursor. NextFeature();
                while (feature != null)
                {<!-- -->
                    int ind = feature.Fields.FindField("OBJECTID");
                    string oid = feature.Value[ind].ToString();
                    IGeometryBag pgeometryBag = null;
                    if (CheckFeatureSelfInsect2(feature))
                    {<!-- -->
                 mes + = String.Format("The feature whose layer OBJECTID is {0} has a self-intersection error", feature.OID);
                    }
                    feature = cursor. NextFeature();
                }
                System.Runtime.InteropServices.Marshal.ReleaseComObject(cursor);

                if (feature != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(feature);
            }
            catch (Exception ex)
            {<!-- -->

            }
        }
          private bool CheckFeatureSelfInsect2(IFeature feature)
        {<!-- -->
            ISpatialReference prj = feature.Shape.SpatialReference;
            IPolygon4 pPolygon4 = feature.Shape as IPolygon4;
            IGeometryBag pOutGeometryBag = pPolygon4.ExteriorRingBag; //Get the outer ring
            IGeometryCollection pOutGmtyCollection = pOutGeometryBag as IGeometryCollection;
            bool isInsect = false;
            for (int i = 0; i < pOutGmtyCollection.GeometryCount; i + + ) // traverse the outer ring
            {<!-- -->
                IGeometry pOutRing = pOutGmtyCollection.get_Geometry(i); //outer ring
                IPointCollection pCol = pOutRing as IPointCollection;//Collection of outer ring nodes
                IPointCollection polylinePointCollection = new PolylineClass();
                for (int j = 0; j < pCol. PointCount - 1; j++ )
                {<!-- -->
                    polylinePointCollection.AddPoint(pCol.get_Point(j));
                }
                IPolyline pPolyline = polylinePointCollection as IPolyline;
                isInsect = Check(pPolyline);
                if (isInsect)
                    break;

                IGeometryBag pInteriotGeometryBag = pPolygon4.get_InteriorRingBag(pOutRing as IRing); //Get the inner ring
                IGeometryCollection pInteriorGeometryCollection = pInteriotGeometryBag as IGeometryCollection;
                for (int k = 0; k < pInteriorGeometryCollection. GeometryCount; k++ )
                {<!-- -->
                    IGeometry pInteriorGeometry = pInteriorGeometryCollection. get_Geometry(k);
                    IPointCollection pincol = pInteriorGeometry as IPointCollection;//Collection of inner ring nodes
                    IPointCollection polylineInPointCollection = new PolylineClass();
                    for (int j = 0; j < pincol. PointCount - 1; j++ )
                    {<!-- -->
                        polylineInPointCollection.AddPoint(pincol.get_Point(j));
                    }
                    IPolyline pInPolyline = polylineInPointCollection as IPolyline;
                    isInsect = Check(pInPolyline);
                    if (isInsect)
                        break;
                }
                if (isInsect)
                    break;
            }

            return isInsect;
        }
        bool Check(IPolyline polylineA)
        {<!-- -->
            ITopologicalOperator3 pTopologicalOperator3 = polylineA as ITopologicalOperator3;
            pTopologicalOperator3.IsKnownSimple_2 = false;

            // check for self-intersection
            esriNonSimpleReasonEnum reason = esriNonSimpleReasonEnum.esriNonSimpleOK;
            if (!pTopologicalOperator3. get_IsSimpleEx(out reason))
            {<!-- -->
                if (reason == esriNonSimpleReasonEnum.esriNonSimpleSelfIntersections)
                {<!-- -->
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(polylineA);
                    return true;
                }
            }

            return false;
        }

Method 2: Based on the NetTopologySuite class library, the NetTopologySuite library has a special method for judging whether the graphics are valid. This method can also be used to check, because my original framework is based on arcgis engine, so there is still a need to convert the geometry of esri to GeoAPI. The Geometries.IGeometry code is as follows:

//The following libraries need to be referenced
using NetTopologySuite.IO;
using NetTopologySuite. Geometries;
using NetTopologySuite. Operation. Valid;

 void topTest()
        {<!-- -->
            string topGdbPath = @"E:\Data\topology.gdb";
            string err = "";
             IWorkspaceFactory pWf = new FileGDBWorkspaceFactoryClass();
            IWorkspace workspace = pWf.OpenFromFile(topGdbPath , 0)
             IFeatureWorkspace pFeatureWorkspace = pWs as IFeatureWorkspace;
            string mes = "";
            IFeatureClass featureClass =pFeatureWorkspace. OpenFeatureClass("SLZY");

            try
            {<!-- -->
                long fCount = featureClass. FeatureCount(null);
                IFeatureCursor cursor = featureClass. Search(null, true);
                IFeature feature = cursor. NextFeature();
                while (feature != null)
                {<!-- -->
                    int ind = feature.Fields.FindField("OBJECTID");
                    string oid = feature.Value[ind].ToString();
                    if (!CheckIsvalid(feature.ShapeCopy))
                    {<!-- -->
                 mes + = String.Format("The feature whose layer OBJECTID is {0} has a self-intersection error", feature.OID);
                    }
                    feature = cursor. NextFeature();
                }
                System.Runtime.InteropServices.Marshal.ReleaseComObject(cursor);

                if (feature != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(feature);
            }
            catch (Exception ex)
            {<!-- -->

            }
        }


    public bool CheckIsvalid(IGeometry polygon)
    {<!-- -->
         var validator = new IsValidOp(ConvertESRIToGeoAPI(polygon));
         return validator. IsValid;
     }
     public GeoAPI.Geometries.IGeometry ConvertESRIToGeoAPI(IGeometry geometry)
     {<!-- -->
         byte[] wkb = ConvertGeometryToWKB(geometry);
         WKBReader reader = new WKBReader();
         return reader. Read(wkb);
     }
     public string ConvertGeometryToWKT(IGeometry geometry)
     {<!-- -->
         byte[] b = ConvertGeometryToWKB(geometry);
         WKBReader reader = new WKBReader();
         GeoAPI.Geometries.IGeometry g = reader.Read(b);
         WKTWriter writer = new WKTWriter();
         return writer. Write(g);
     }
     public byte[] ConvertGeometryToWKB(IGeometry geometry)
     {<!-- -->
         IWkb wkb = geometry as IWkb;
         IGeometryFactory3 factory = new GeometryEnvironment() as IGeometryFactory3;
         byte[] b = factory.CreateWkbVariantFromGeometry(geometry) as byte[];
         return b;
     }