面图层检查图形自相交方法C#

方法一:基于arcgis engine 处理,因为基于AE的拓扑检查规则中只有线自相交检查,所以这里的处理逻辑就是遍历面要素,然后渠道每个面要素的内外环,再独立构建成线要素,使用拓扑去检查,代码如下:

        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("图层OBJECTID为{0}的要素存在自相交错误", 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;  //获取外部环
            IGeometryCollection pOutGmtyCollection = pOutGeometryBag as IGeometryCollection;
            bool isInsect = false;
            for (int i = 0; i < pOutGmtyCollection.GeometryCount; i++)  //对外部环遍历
            {
                IGeometry pOutRing = pOutGmtyCollection.get_Geometry(i); //外部环
                IPointCollection pCol = pOutRing as IPointCollection;//外环节点集合
                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);  //获取内部环
                IGeometryCollection pInteriorGeometryCollection = pInteriotGeometryBag as IGeometryCollection;
                for (int k = 0; k < pInteriorGeometryCollection.GeometryCount; k++)
                {
                    IGeometry pInteriorGeometry = pInteriorGeometryCollection.get_Geometry(k);
                    IPointCollection pincol = pInteriorGeometry as IPointCollection;//内环节点集合
                    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;

            // 检查自相交
            esriNonSimpleReasonEnum reason = esriNonSimpleReasonEnum.esriNonSimpleOK;
            if (!pTopologicalOperator3.get_IsSimpleEx(out reason))
            {
                if (reason == esriNonSimpleReasonEnum.esriNonSimpleSelfIntersections)
                {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(polylineA);
                    return true;
                }
            }

            return false;
        }

方法二:基于NetTopologySuite类库, NetTopologySuite库里有专门判断图形是否有效的方法,使用这个方法也可检查,因为我原框架是基于arcgis engine的,所以这里还存在要将esri的geometry转换为GeoAPI.Geometries.IGeometry 代码如下:

//需引用以下库
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("图层OBJECTID为{0}的要素存在自相交错误", 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;
     }

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值