基于ArcEngine实现要素合并、裁剪及重叠检测的核心功能代码示例

一、要素合并(Union)

1. 多要素几何合并(ConstructUnion)

public IGeometry MergeFeatures(IFeatureClass featureClass)
{
    if (featureClass == null) return null;

    IGeoDataset geoDataset = featureClass as IGeoDataset;
    IGeometryBag geometryBag = new GeometryBagClass();
    geometryBag.SpatialReference = geoDataset.SpatialReference;

    IFeatureCursor cursor = featureClass.Search(null, false);
    IGeometryCollection geometryCollection = geometryBag as IGeometryCollection;

    while (cursor.NextFeature() != null)
    {
        geometryCollection.AddGeometry(cursor.Feature.ShapeCopy, ref Missing.Value, ref Missing.Value);
    }
    Marshal.ReleaseComObject(cursor);

    ITopologicalOperator unionOp = new PolygonClass();
    unionOp.ConstructUnion(geometryCollection as IEnumGeometry);
    return unionOp as IGeometry;
}

技术要点

  • 使用ConstructUnion替代逐个Union操作,性能提升显著(适用于1000+要素场景)

  • 需确保所有要素空间参考一致,否则需先投影转换


二、要素裁剪(Clip)

1. 几何裁剪(Intersect/Difference)

public IGeometry ClipGeometry(IFeature clipFeature, IGeometry sourceGeometry)
{
    ITopologicalOperator2 topoOp = sourceGeometry as ITopologicalOperator2;
    if (clipFeature.SpatialReference != sourceGeometry.SpatialReference)
    {
        clipFeature.Project(sourceGeometry.SpatialReference);
    }

    IGeometry clipShape = clipFeature.ShapeCopy;
    return topoOp.Intersect(clipShape, esriGeometryDimension.esriGeometry2Dimension);
}

2. 使用GP工具裁剪(支持空间范围)

public void ExecuteClipTool(IFeatureClass inputFC, IFeatureClass clipFC, string outputPath)
{
    Geoprocessor gp = new Geoprocessor();
    gp.OverwriteOutput = true;

    Clip clipTool = new Clip();
    clipTool.in_features = inputFC;
    clipTool.clip_features = clipFC;
    clipTool.out_feature_class = outputPath;

    IVariantArray parameters = new VarArray();
    parameters.Add(inputFC);
    parameters.Add(clipFC);
    parameters.Add(outputPath);

    gp.Execute("Clip_analysis", parameters, null);
}

技术要点

  • ConstructUnion适用于多要素合并,Intersect用于精确裁剪

  • 处理大型数据时建议使用FeatureClassToFeatureClass批量操作


三、重叠检测(Overlap Detection)

1. 空间索引快速检测

public List<int> FindOverlappingFeatures(IFeatureClass fc)
{
    List<int> overlaps = new List<int>();
    IFeatureIndex index = new FeatureIndexClass();
    index.FeatureClass = fc;
    index.Index(null, ((IGeoDataset)fc).Extent);

    IFeatureCursor cursor = fc.Search(null, false);
    IFeature feature = null;
    while ((feature = cursor.NextFeature()) != null)
    {
        IIndexQuery2 indexQuery = (IIndexQuery2)index;
        object intersectedOids;
        indexQuery.IntersectedFeatures(feature.Shape, out intersectedOids);

        int[] oids = (int[])intersectedOids;
        for (int i = 0; i < oids.Length; i++)
        {
            if (oids[i] != feature.OID)
            {
                overlaps.Add(feature.OID);
                break;
            }
        }
    }
    Marshal.ReleaseComObject(cursor);
    return overlaps;
}

2. 拓扑关系验证

public bool CheckOverlap(IFeature featureA, IFeature featureB)
{
    IRelationalOperator2 relOp = featureA.Shape as IRelationalOperator2;
    return relOp.Overlaps(featureB.Shape);
}

技术要点

  • 空间索引可将检测效率提升3-5倍(适用于10万+要素场景)

  • 使用IRelationalOperator2进行精确拓扑关系判断


四、性能优化

  1. 批量处理

    public void BatchProcess(IFeatureClass fc, Action<IFeature> action)
    {
        IFeatureCursor cursor = fc.Search(null, false);
        IFeature feature;
        while ((feature = cursor.NextFeature()) != null)
        {
            action(feature);
        }
        Marshal.ReleaseComObject(cursor);
    }
    
  2. 内存管理

    using (var release = new ComReleaser())
    {
        release.ManageLifetime(featureCursor);
        release.ManageLifetime(geometryBag);
    }
    
  3. 并行计算

    Parallel.ForEach(features, feature => 
    {
        var overlap = CheckOverlap(feature, referenceFeature);
    });
    

五、应用场景对比

方法 适用场景 性能表现 空间复杂度
ConstructUnion 多要素合并(1000+要素) O(n log n)
ConstructUnion 断开线要素合并 O(n)
Clip 矢量数据裁剪(精确边界) O(n)
空间索引检测 大数据量重叠检测 O(1)~O(log n)

六、调试建议

  1. 几何验证

    if (!feature.Shape.IsValid)
    {
        Debug.WriteLine($"要素 {feature.OID} 几何无效");
    }
    
  2. 拓扑错误处理

    catch (TopologyException ex)
    {
        Debug.WriteLine($"拓扑错误: {ex.Message}");
    }
    
  3. 可视化验证

    ITopologicalOperator op = clipGeometry as ITopologicalOperator;
    op.Simplify(); // 简化几何形状
    

参考代码 ArcEngine基本功能实现:要素合并、裁剪及检测要素重叠 www.youwenfan.com/contentcnr/112154.html

七、扩展功能实现

  1. 批量合并

    public void BatchMerge(IFeatureClass[] featureClasses, string outputPath)
    {
        IWorkspaceFactory wsf = new ShapefileWorkspaceFactory();
        IWorkspace ws = wsf.OpenFromFile(outputPath, 0);
        IFeatureClass outputFC = CreateOutputFC(ws);
    
        foreach (var fc in featureClasses)
        {
            var unionGeom = MergeFeatures(fc);
            IFeatureBuffer buffer = outputFC.CreateFeatureBuffer();
            buffer.Shape = unionGeom;
            outputFC.AddFeature(buffer);
        }
    }
    
  2. 动态裁剪

    public IGeometry DynamicClip(IPolygon clipArea, IFeatureClass inputFC)
    {
        IFeatureCursor cursor = inputFC.Search(null, false);
        IGeometryBag resultBag = new GeometryBagClass();
    
        while (cursor.NextFeature() != null)
        {
            var feature = cursor.Feature;
            var clipped = ClipGeometry(clipArea, feature.Shape);
            if (clipped != null)
            {
                resultBag.AddGeometry(clipped, ref Missing.Value, ref Missing.Value);
            }
        }
        return resultBag as IGeometry;
    }
    
posted @ 2026-02-11 16:47  yes_go  阅读(28)  评论(0)    收藏  举报