基于C#的ArcEngine二次开发34:使用ConstructUnion方法进行多要素合并

目录

1. 面要素合并

1.1 代码

1.2 效果演示

2 根据属性合并线要素

2.1 遇到的问题

2.3 代码

2.5 总结

3 根据几何合并

3.1 程序思路和实现过程

3.2 程序实例和结果

3.3 代码


说明:

使用ContructionUnion进行要素合并得到的要素实际上是复合要素,即一个集合要素由多个几何图形构成,而我们常见的要素一般是一个几何要素只包含一个几何图形

如果合并之后,还需要拆分操作请参考博客文章:基于C#的ArcEngine二次开发23:复合要素的识别与导出

本文为网络搜集代码整理,希望方便大家借鉴参考,如有侵权,请联系删除!

以下代码及演示来源于以下博客:

第一部分:ArcEngine合并要素

第二部分: ArcEngine中合并断开的线要素(根据几何判断)

第三部分:ArcEngine环境下合并断开的线要素(根据属性)

感谢原作者

本文的第一部分,亦在公众号【运筹优化与图像处理算法编程】公众号同步刊发,欢迎关注!

0 基础知识

0.1 ArcGIS常用工具:union、merge、append、dissolve区别

原文来自https://blog.csdn.net/sisiiiiiii/article/details/39178913

  • union(联合)

      要求输入的要素必须是多边形,即求得两个及以上多边形的并集,对输入要素的属性字段没有要求,输出要素是所有输入的属性的集合。如下图输入三个要素面,输出要素面为7个。

                   

  • merge(合并)

      将数据类型相同的多个输入数据集合并为新的单个输出数据集,属性字段也合并成两个要素属性全集

          

  • append(追加)

      将多个输入数据集追加到现有目标数据集,与合并区别是合并生成新的要素集,追加是在现有要素基础上。

                                    

  • dissolve(融合)

      对于融合需要选择一个或者多个指定的属性字段,融合的要素必须具有相同的几何类型,可以简单理解为具有相同属性要素集合成一个要素集。融合后的属性字段仅输出融合前指定的。

面状数据调整,需要把多个面融合为一个面,属性保留一种,那就需要用到融合工具(dissolve)

0.2 融合示例ArcGIS演示

文献来源:https://blog.csdn.net/aganliang/article/details/81560293

 下面详细讲解使用方法,如图所示。

1.先把属性改成一样

2.打开融合工具

3.自动生成的字段不要勾选

4.结果如图所示。

要素融合+要素转点的代码实现:

//在D:\data目录下创建temp.gdb文件夹,存储计算的中间结果
public check(string inPath, string checkLayerName)
{
    //初始化GP工具
    ESRI.ArcGIS.Geoprocessor.Geoprocessor pGeoprocessor = new ESRI.ArcGIS.Geoprocessor.Geoprocessor {OverwriteOutput = true, AddOutputsToMap = false};
    //创建GDB文件
    CreateFileGDB processor1 = new CreateGDB {out_folder_path = @"D:\data", out_name = "temp.gdb"}; 
    pGeoprocessor.Execute(processor1, null);
    
    string lcaPath = inPath + "\\" + checkLayerName;
    string gdbPath = processor1.out_folder_path + "\\" + processor1.out_name);

    //面融合
    string dissolveLayerName = gdbPath + "\\dissolve";
    pGeoprocessor.Execute(areaDissolve(lcaPath, dissolveLayerName), null);
    
    //要素转点
    string featureToPointLayerName= gdbPath + "\\dissolve";
    pGeoprocessor.Execute(featureToPoint(lcaPath, featureToPointLayerName), null);


}

//面融合函数
public void areaDissolve(string lcaPath, string dissolveLayerName)
{
    Dissolve disolve = new Disolve {};
    dissolve.in_features = lcaPath;
    dissolve.out_features = dissolveLayerName;
    dissolve.dissolve_fields = "FEAID";
    return disolve;
}
//要素转点
public void featureToPoint(string lcaPath, string featureToPointLayerName)
{
    FeatureToPoint pFeaToPt = new FeatureToPoint {};
    pFeaToPt.in_features = lcaPath;
    pFeaToPt.out_features_class = featureToPointLayerName;
    pFeaToPt.point_location = "INSIDE";
    return pFeaToPt;
}

 

1. 面要素合并

1.1 代码

开发环境:VS2013 + ArcEngine 10.4
在数据量较大时,请用ITopologicalOperator的ConstructUnion方法,而不是一个一个Union

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Output;
using ESRI.ArcGIS.SystemUI;

namespace WindowsFormsApplication2
{
    public class MergeTool
    {
        /// <summary>
        /// 输入要素
        /// </summary>
        private IFeatureClass in_FeatureClass;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="in_FeatureClass"></param>
        public MergeTool(IFeatureClass in_FeatureClass)
        {
            this.in_FeatureClass = in_FeatureClass;
        }

        /// <summary>
        /// 获取空间参考
        /// </summary>
        /// <returns></returns>
        private ISpatialReference GetSpatialReference()
        {
            IGeoDataset pGeoDataset = in_FeatureClass as IGeoDataset;
            ISpatialReference pSpatialReference = pGeoDataset.SpatialReference;
            return pSpatialReference;
        }

        /// <summary>
        /// 合并几何体
        /// </summary>
        /// <returns></returns>
        private IGeometry GetMergeGeometry()
        {
            IGeometryBag pGeometryBag = new GeometryBag() as IGeometryBag;
            pGeometryBag.SpatialReference = GetSpatialReference();
            IGeometryCollection pGeometryCollection = pGeometryBag as IGeometryCollection;

            // 属性过滤
            IQueryFilter pQueryFilter = new QueryFilter();
            pQueryFilter.AddField("Shape");

            // 要素游标
            IFeatureCursor pFeatureCursor = in_FeatureClass.Search(pQueryFilter, true);
            IFeature pFeature = pFeatureCursor.NextFeature();
            if (pFeature == null)
            {
                return null;
            }

            // 遍历游标
            object missing = Type.Missing;
            while (pFeature != null)
            {
                pGeometryCollection.AddGeometry(pFeature.ShapeCopy, ref missing, ref missing);
                pFeature = pFeatureCursor.NextFeature();
            }
            Marshal.ReleaseComObject(pFeatureCursor);

            // 合并要素
            ITopologicalOperator pTopologicalOperator = null;
            if (in_FeatureClass.ShapeType == esriGeometryType.esriGeometryPoint)
            {
                pTopologicalOperator = new Multipoint() as ITopologicalOperator;
                pTopologicalOperator.ConstructUnion(pGeometryCollection as IEnumGeometry);
            }
            else if (in_FeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
            {
                pTopologicalOperator = new Polyline() as ITopologicalOperator;
                pTopologicalOperator.ConstructUnion(pGeometryCollection as IEnumGeometry);
            }
            else
            {
                pTopologicalOperator = new Polygon() as ITopologicalOperator;
                pTopologicalOperator.ConstructUnion(pGeometryCollection as IEnumGeometry);
            }
            return pTopologicalOperator as IGeometry;
        }

        /// <summary>
        /// 执行工具
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public IFeatureClass ExecuteTool(string filePath)
        {
            IGeometryDef pGeometryDef = new GeometryDef();
            IGeometryDefEdit pGeometryDefEdit = pGeometryDef as IGeometryDefEdit;
            if (in_FeatureClass.ShapeType == esriGeometryType.esriGeometryPoint)
            {
                pGeometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryMultipoint;
                pGeometryDefEdit.HasM_2 = false;
                pGeometryDefEdit.HasZ_2 = false;
                pGeometryDefEdit.SpatialReference_2 = GetSpatialReference();
            }
            else if (in_FeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
            {
                pGeometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolyline;
                pGeometryDefEdit.HasM_2 = false;
                pGeometryDefEdit.HasZ_2 = false;
                pGeometryDefEdit.SpatialReference_2 = GetSpatialReference();
            }
            else
            {
                pGeometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolygon;
                pGeometryDefEdit.HasM_2 = false;
                pGeometryDefEdit.HasZ_2 = false;
                pGeometryDefEdit.SpatialReference_2 = GetSpatialReference();
            }

            // 字段集合
            IFields pFields = new Fields();
            IFieldsEdit pFieldsEdit = pFields as IFieldsEdit;

            // Shape
            IField pField = new Field();
            IFieldEdit pFieldEdit = pField as IFieldEdit;
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
            pFieldEdit.GeometryDef_2 = pGeometryDef;
            pFieldEdit.AliasName_2 = "Shape";
            pFieldEdit.Name_2 = "Shape";
            pFieldEdit.IsNullable_2 = false;
            pFieldEdit.Required_2 = true;
            pFieldsEdit.AddField(pField);

            // 创建要素类
            IWorkspaceFactory pWorkspaceFactory = new ShapefileWorkspaceFactory();
            IWorkspace pWorkspace = pWorkspaceFactory.OpenFromFile(System.IO.Path.GetDirectoryName(filePath), 0);
            IFeatureWorkspace pFeatureWorkspace = pWorkspace as IFeatureWorkspace;
            IFeatureClass pFeatureClass = pFeatureWorkspace.CreateFeatureClass(System.IO.Path.GetFileName(filePath), pFields, null, null, esriFeatureType.esriFTSimple, "Shape", "");

            // 插入要素
            IFeatureBuffer pFeatureBuffer = pFeatureClass.CreateFeatureBuffer();
            IFeatureCursor pFeatureCursor = pFeatureClass.Insert(true);
            pFeatureBuffer.Shape = GetMergeGeometry();
            pFeatureCursor.InsertFeature(pFeatureBuffer);
            pFeatureCursor.Flush();
            return pFeatureClass;
        }
    }
}

1.2 效果演示

合并之前

在这里插入图片描述

合并之后

在这里插入图片描述

2 根据属性合并线要素

2.1 遇到的问题

 最近遇到在线要素(矢量数据)中,一条完整的道路、河流等往往是断开的,如下图1所示:

 

 

     2.2 思路与结果

      在ArcGIS Desktop中没有相关的工具可以将这些断开的线要素进行自动合并,今天自己写了一个Arcmap上的一个插件,实现当点击插件按钮后,对地图窗口中断开的线要素进行合并。合并的依据是具有相同NAME属性(如长沙-张家界高速)的Polyline要素进行合并,然后存储在另一个线要素图层中。

      程序运行的结果如下,这样本来属于同一段道路的多个Polyline就合并成一条Polyline:

2.3 代码

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
using ESRI.ArcGIS.ArcMapUI;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;

namespace MergeDisconnectPolylineAddin
{
    public class MergePolyline : ESRI.ArcGIS.Desktop.AddIns.Button
    {
        
        IMap map = null;
        IActiveView pActiveView = null;
        //private List<IPolyline> DisconnPolylineList = new List<IPolyline>();

        public MergePolyline()
        {
            IMxDocument mxDoc = ArcMap.Application.Document as IMxDocument;
            map = mxDoc.FocusMap;
            pActiveView = mxDoc.ActivatedView;
        }

        protected override void OnClick()
        {
            //
            //  TODO: Sample code showing how to access button host
            //
            ArcMap.Application.CurrentTool = null;

            //计算程序耗时
            DateTime beforDT = System.DateTime.Now;
            
            List<string> distinctString = getDistinctNAMEValue();
            MergePloyline(distinctString);

            DateTime afterDT = System.DateTime.Now;
            TimeSpan ts = afterDT.Subtract(beforDT);
            MessageBox.Show("线要素合并结束,运行程序共耗时约:"+ ts.Minutes+"分钟");
        }
        
        public List<string> getDistinctNAMEValue()
        {
            IFeatureLayer featureLayer = map.get_Layer(0) as IFeatureLayer;
            IFeatureClass featureClass = featureLayer.FeatureClass;
            IQueryFilter queryFilter = new QueryFilterClass();
            queryFilter.WhereClause = "";
            IFeatureCursor pFeatCursor = featureClass.Search(queryFilter, false);
            IFeature pFeature = pFeatCursor.NextFeature();
            ArrayList fieldArray = new ArrayList();
            List<string> distinctString = new List<string>();
            while (pFeature != null)
            {
                if (featureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
                {
                    IFields fields = pFeatCursor.Fields;
                    int fieldIndex = fields.FindField("NAME");
                    string field_NAME = (string)pFeature.get_Value(fieldIndex);
                    fieldArray.Add(field_NAME);
                }
                pFeature = pFeatCursor.NextFeature();
            }
            distinctString = removeSameString(fieldArray);
            return distinctString;
        }

        public void MergePloyline(List<string> DistinctNameValue)
        {
            IFeatureLayer featureLayer = map.get_Layer(0) as IFeatureLayer;
            IFeatureClass featureClass = featureLayer.FeatureClass;

            //IDataset dataset = featureClass as IDataset;
            //IWorkspaceEdit workspaceEdit = dataset.Workspace as IWorkspaceEdit;
            //Type.Missing指的是空类型,因为有些方法你传null给它会出错的,必须要用Type.Missing.
            object Missing = Type.Missing;
            //workspaceEdit.StartEditing(true);
            //workspaceEdit.StartEditOperation();
            //string field_NAME = "";

            for (int i = 0; i < DistinctNameValue.Count; i++)
            {
                IQueryFilter queryFilter = new QueryFilterClass();
                queryFilter.WhereClause = "";
                IFeatureCursor pFeatCursor = featureClass.Search(queryFilter, false);
                IFeature pFeature = pFeatCursor.NextFeature();

                IFeature pFeatureFirst = pFeature;
                //List<IPolyline> toMergePolylineList = new List<IPolyline>();

                IGeometryCollection Geometrybag = new GeometryBagClass();
                ITopologicalOperator2 pTopOperatorFirst = null;
                IGeometry geometrySecond = null;
                IGeometry pGeometryFirst = null;
                bool bSwitch = true;
                while (pFeature != null)
                {
                    map.SelectFeature(featureLayer, pFeature);
                    if (featureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
                    {                       
                        //IPolyline polyline = geometry as IPolyline;
                        IFields fields = pFeatCursor.Fields;
                        int fieldIndex = fields.FindField("NAME");
                        string field_NAME = (string)pFeature.get_Value(fieldIndex);
                        
                        if (field_NAME == DistinctNameValue[i])
                        {
                            if (bSwitch)
                            {
                                //将当前name字段相同的feature中的第一个feature传给pFeatureFirst
                                pFeatureFirst = pFeature;
                                pGeometryFirst = pFeature.Shape;
                                pTopOperatorFirst = (ITopologicalOperator2) pGeometryFirst;
                                pTopOperatorFirst.IsKnownSimple_2 = false;
                                pTopOperatorFirst.Simplify();
                                pGeometryFirst.SnapToSpatialReference();
                                bSwitch = false;
                                //break;
                            }
                            else
                            {
                                //geometrySecond = pFeature.ShapeCopy;
                                geometrySecond = pFeature.Shape;
                                Geometrybag.AddGeometry(geometrySecond, ref Missing, ref Missing);
                                //toMergePolylineList.Add(polyline);
                            }                           
                        }
                        //DisconnPolylineList.Add(polyline);
                    }
                    pFeature = pFeatCursor.NextFeature();
                }
                IEnumGeometry tEnumGeometry = (IEnumGeometry)Geometrybag;
                //IGeometry mergeGeomery = null;
                pTopOperatorFirst.ConstructUnion(tEnumGeometry);

                pTopOperatorFirst.IsKnownSimple_2 = false;
                pTopOperatorFirst.Simplify();
                pFeatureFirst.Shape = pGeometryFirst;
                //pFeatureFirst.Store();
                IFeatureLayer featureLayer2 = map.get_Layer(1) as IFeatureLayer;
                IFeatureClass featureClass2 = featureLayer2.FeatureClass;
                AddPolyline(featureClass2, pGeometryFirst);
            }
            //workspaceEdit.StopEditOperation();
            //workspaceEdit.StopEditing(true);           
        }
        private void AddPolyline(IFeatureClass pFeatureClass, IGeometry polyline)
        {
            IFeatureBuffer featureBuffer = pFeatureClass.CreateFeatureBuffer();
            IFeatureCursor featureCursor;
            featureCursor = pFeatureClass.Insert(true);
            featureBuffer.Shape = polyline;
            featureCursor.InsertFeature(featureBuffer);
            featureCursor.Flush();
            System.Runtime.InteropServices.Marshal.ReleaseComObject(featureCursor);
        }
        public List<string> removeSameString(ArrayList stringArray)
        {
            //List用于存储从数组里取出来的不相同的元素
            List<string> distinctString = new List<string>();
            foreach (string eachString in stringArray)
            {
                if (!distinctString.Contains(eachString))
                    distinctString.Add(eachString);
            }
            return distinctString;
        }

        protected override void OnUpdate()
        {
            Enabled = ArcMap.Application != null;
        }
    }

}

2.5 总结

      这个插件还有一些不足的地方,如不是从线要素首尾点相邻的角度寻找相邻点(这种方法存在判断三条线要素交叉而形成的节点的判断和是否进行合并的问题和难点),在下一篇随笔里面会介绍从纯几何学的角度实现线要素的连接的实现。

3 根据几何合并

通过几何条件判断的方式连接断开的线要素的ArcGIS 插件完成,在这里把思路和代码和大家分享下:

3.1 程序思路和实现过程

1.首先读取shp线文件,将各条线要素遍历,存储在List<IFeature>,这里之所以不存在List<IPolyline>和List<IGeometry>中的原因是后两者会丢失要素的属性信息;

2.为了简化合并算法的逻辑和复杂性,采用分治思想。将线要素分为需要进行合并和不需要进行合并(独立的线,ToPoint或FromPoint是“节点”的线和ToPoint,FromPoint均是“节点”线)的两大类,分别存储在两个集合中;

3.现在只需对需要进行合并的的线要素集合进行合并操作。首先从集合中选取一条Polyline,然后在集合剩下的元素中寻找与其ToPoint或FromPoint相同的线要素,然后使用ITopologicalOperator2.Union()方法进行合并,然后寻找和合并后新的Polyline的ToPoint或FromPoint相同的线要素继续合并,没合并一次,就将合并入的Polyline从集合中移除,直到剩下的Polyline不可和当前合并的Polyline合并为止,这样就得到了第一条合并好的Polyline。接着从集合剩下的线要素再找一条Polyline开始新一轮合并操作,直到List<IFeature>为空,整个合并操作结束;

4.得到合并好的List<IFeature> mergeResultLineList后,需要为其添加属性(NAME等字段),通过IFeatureBuffer接口写入shape和Fields,然后Flush到文件中,结束。

3.2 程序实例和结果

运行结果图
合并前属性表

 

合并后属性表

 

3.3 代码

public class MergeDisconnectLine : ESRI.ArcGIS.Desktop.AddIns.Button
    {

        public int CountPercent { get; set; }
        IMap map = null;
        private List<IFeature> DisconnPolylineList = new List<IFeature>();
        private List<IFeature> firstRowFeatureList = new List<IFeature>();

        public MergeDisconnectLine()
        {
            IMxDocument mxDoc = ArcMap.Application.Document as IMxDocument;
            map = mxDoc.FocusMap;
        }
        protected override void OnClick()
        {
            //
            //  TODO: Sample code showing how to access button host
            //
            ArcMap.Application.CurrentTool = null;

            //计算程序耗时
            DateTime beforDT = System.DateTime.Now;
            //Application.EnableVisualStyles();
            //Application.SetCompatibleTextRenderingDefault(false);
            ProgressBar pBar = new ProgressBar();
            //Application.Run(new ProgressBar());           
            List<IFeature> allPolylineList = getAllPolyline();
            List<IFeature> noNeedUnionLineList = getWithoutNeedUnionLineList(allPolylineList);
            List<IFeature> toUnionLineList = GetToUnionLineList(allPolylineList, noNeedUnionLineList);
            List<IFeature> unionLineList = MergeLineListOperate(toUnionLineList);
            AddField();
            WriteNoNeedUnionLineToFile(noNeedUnionLineList);
            WriteUnionLineToFile(unionLineList, firstRowFeatureList);
            DateTime afterDT = System.DateTime.Now;
            TimeSpan ts = afterDT.Subtract(beforDT);
            int minutes = ts.Minutes;
            int seconds = ts.Seconds%60;
            //pBar.Hide();
            MessageBox.Show("线要素合并结束,运行程序共耗时约:" + minutes + "分"+ seconds + "秒");
        }
        //获取shp文件中所有的Polyline(IFeature)对象
        public List<IFeature> getAllPolyline()
        {
            IFeatureLayer featureLayer = map.get_Layer(1) as IFeatureLayer;
            IFeatureClass featureClass = featureLayer.FeatureClass;
            IQueryFilter queryFilter = new QueryFilter();
            queryFilter.WhereClause = "";
            IFeatureCursor pFeatCursor = featureClass.Search(queryFilter, false);
            IFeature pFeature = pFeatCursor.NextFeature();

            while (pFeature != null)
            {
                if (featureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
                {
                    DisconnPolylineList.Add(pFeature);
                }
                pFeature = pFeatCursor.NextFeature();                 
            }
            return DisconnPolylineList;
        }

        //获取需要进行合并的线(是noNeedUnionLineList的补集)
        public List<IFeature> GetToUnionLineList(List<IFeature> allPolylineList, List<IFeature> noNeedUnionLineList)
        {
            List<IFeature> toUnionLineList = allPolylineList;
            foreach (IFeature featureLine in noNeedUnionLineList)
            {
                toUnionLineList.Remove(featureLine);
            }
            return toUnionLineList;
        }

        //获取不需要进行合并的线(独立线,一端是节点的线,和两端都是节点的线)       
        public List<IFeature> getWithoutNeedUnionLineList(List<IFeature> allPolylineList)
        {
            List<IFeature> noNeedUnionLineList = new List<IFeature>();
            foreach (IFeature featureLine in allPolylineList)
            {
                int count = featureLine.Fields.FieldCount;
                List<IFeature> allPolylineListCopy = allPolylineList;
                IGeometry geoLine = featureLine.Shape;
                IPolyline lineFirst = geoLine as IPolyline;
                IPoint startPt1 = lineFirst.FromPoint;
                IPoint endPt1 = lineFirst.ToPoint;
                int fromFlag = 0;
                int toFlag = 0;
                for (int i = 0; i < allPolylineListCopy.Count; i++)
                {
                    IFeature line2 = allPolylineListCopy[i];
                    IGeometry geoLine2 = line2.Shape;
                    IPolyline lineSecond = geoLine2 as IPolyline;
                    IPoint startPt2 = lineSecond.FromPoint;
                    IPoint endPt2 = lineSecond.ToPoint;
                    //FromPoint相同的点
                    if ((startPt1.X == startPt2.X && startPt1.Y == startPt2.Y) ||
                        (startPt1.X == endPt2.X && startPt1.Y == endPt2.Y))
                    {
                        fromFlag++;
                    }
                    //ToPoint相同的点
                    if ((endPt1.X == endPt2.X && endPt1.Y == endPt2.Y) ||
                    (endPt1.X == startPt2.X && endPt1.Y == startPt2.Y))
                    {
                        toFlag++;
                    }
                }
                if (fromFlag > 2 || toFlag > 2 || (fromFlag == 1 && toFlag == 1))
                {
                    noNeedUnionLineList.Add(featureLine);
                    //noNeedUnionLineFileds.Add(featureLine.Fields);
                }
            }
            return noNeedUnionLineList;
        }

        //将需要进行合并的线要素(没有节点)集合进行合并,结果为多条线       
        public List<IFeature> MergeLineListOperate(List<IFeature> toUnionLineList)
        {
            List<IFeature> mergeResultLineList = new List<IFeature>();
            int CountPercent = 0;
            while (toUnionLineList.Count > 0)
            {
                CountPercent++;
                //初始化当前合并的线要素
                IFeature unionCurrentLine = toUnionLineList[0];
                //将第一个要素的属性字段值作为最终合并线要素的值
                firstRowFeatureList.Add(unionCurrentLine);
                List<IFeature> currentMergeLineList = new List<IFeature>();
                int count2 = 0;
                do
                {
                    count2++;
                    IFeature featureFirst = unionCurrentLine;
                    IGeometry geoLineFirst = featureFirst.Shape;
                    IPolyline lineFirst = geoLineFirst as IPolyline;
                    IPoint startPt1 = lineFirst.FromPoint;
                    IPoint endPt1 = lineFirst.ToPoint;
                    toUnionLineList.Remove(featureFirst);
                    currentMergeLineList.Clear();
                    currentMergeLineList.Add(featureFirst); 

                    List<IFeature> allPolylineListTemp1 = new List<IFeature>();
                    List<IFeature> allPolylineListTemp2 = new List<IFeature>();
                    int bStart1 = 0;
                    int bStart2 = 0;
                    for (int j = 0; j < toUnionLineList.Count; j++)
                    {
                        IFeature featureSecond = toUnionLineList[j];
                        IGeometry geoLineSecond = featureSecond.Shape;
                        IPolyline lineSecond = geoLineSecond as IPolyline;
                        IPoint startPt2 = lineSecond.FromPoint;
                        IPoint endPt2 = lineSecond.ToPoint;

                        if ((startPt1.X == startPt2.X && startPt1.Y == startPt2.Y) ||
                            (startPt1.X == endPt2.X && startPt1.Y == endPt2.Y))
                        {
                            bStart1++;
                            if (bStart1 > 0)
                            {
                                allPolylineListTemp1.Add(featureSecond);
                                currentMergeLineList.AddRange(allPolylineListTemp1);
                                toUnionLineList.Remove(featureSecond);
                            }
                        }
                        if ((endPt1.X == endPt2.X && endPt1.Y == endPt2.Y) ||
                            (endPt1.X == startPt2.X && endPt1.Y == startPt2.Y))
                        {
                            bStart2++;
                            if (bStart2 > 0)
                            {
                                allPolylineListTemp2.Add(featureSecond);
                                currentMergeLineList.AddRange(allPolylineListTemp2);
                                toUnionLineList.Remove(featureSecond);
                            }

                        }
                       
                    }
                    if (currentMergeLineList.Count > 1)
                    {
                        unionCurrentLine = UnionCurrentLineList(currentMergeLineList);
                    }
                    else
                    {
                        int ii = 0;
                    }
                } while (currentMergeLineList.Count > 1);

                mergeResultLineList.Add(unionCurrentLine);
            }
            return mergeResultLineList;
        }

        //为待写入图层添加Name和GB字段
        public void AddField()
        {
            IFeatureLayer featureLayer2 = map.get_Layer(0) as IFeatureLayer;
            IFeatureClass featureClass2 = featureLayer2.FeatureClass;
            IClass pClass = featureClass2 as IClass;
            IField fld1 = new Field();
            IField fld2 = new Field();
            IFieldEdit2 fld_NAME = fld1 as IFieldEdit2;
            IFieldEdit2 fld_GB = fld2 as IFieldEdit2;
            fld_NAME.Type_2 = esriFieldType.esriFieldTypeString;
            fld_NAME.Name_2 = "NAME";
            fld_GB.Type_2 = esriFieldType.esriFieldTypeString;
            fld_GB.Name_2 = "GB";
            pClass.AddField(fld_GB);
            pClass.AddField(fld_NAME);
            
        }

        public void WriteNoNeedUnionLineToFile(List<IFeature> pLineList)
        {           
            foreach (IFeature featureLine in pLineList)
            {
                IFeatureLayer featureLayer2 = map.get_Layer(0) as IFeatureLayer;
                IFeatureClass featureClass2 = featureLayer2.FeatureClass;          
                IFeatureBuffer featureBuffer = featureClass2.CreateFeatureBuffer();
                IFeatureCursor featureCursor;
                featureCursor = featureClass2.Insert(true);               
                IGeometry pGeometry = featureLine.Shape;
                featureBuffer.Shape = pGeometry;
                int NAME_Index = featureLine.Fields.FindField("NAME");
                int GB_Index = featureLine.Fields.FindField("GB");
                string name = featureLine.get_Value(NAME_Index).ToString();
                string gb = featureLine.get_Value(GB_Index).ToString();
                int fieldindex1 = featureBuffer.Fields.FindField("NAME");
                int fieldindex2 = featureBuffer.Fields.FindField("GB");
                if (fieldindex1 >= 0)
                {
                    featureBuffer.set_Value(fieldindex1, name);
                }
                if (fieldindex2 >= 0)
                {
                    featureBuffer.set_Value(fieldindex2, gb);
                }
                featureCursor.InsertFeature(featureBuffer);
                featureCursor.Flush();
                System.Runtime.InteropServices.Marshal.ReleaseComObject(featureCursor);               
            }           
        }
        public void WriteUnionLineToFile(List<IFeature> mergeResultLineList, List<IFeature> firstFeatureList)
        {
            int index = 0;
            foreach (IFeature featureLine in mergeResultLineList)
            {
                IFeatureLayer featureLayer2 = map.get_Layer(0) as IFeatureLayer;
                IFeatureClass featureClass2 = featureLayer2.FeatureClass;
                IFeatureBuffer featureBuffer = featureClass2.CreateFeatureBuffer();
                IFeatureCursor featureCursor;
                featureCursor = featureClass2.Insert(true);
                IGeometry pGeometry = featureLine.Shape;
                featureBuffer.Shape = pGeometry;
                int NAME_Index = firstFeatureList[index].Fields.FindField("NAME");
                int GB_Index = firstFeatureList[index].Fields.FindField("GB");
                string name = firstFeatureList[index].get_Value(NAME_Index).ToString();
                string gb = firstFeatureList[index].get_Value(GB_Index).ToString();
                int fieldindex1 = featureBuffer.Fields.FindField("NAME");
                int fieldindex2 = featureBuffer.Fields.FindField("GB");
                if (fieldindex1 >= 0)
                {
                    featureBuffer.set_Value(fieldindex1, name);
                }
                if (fieldindex2 >= 0)
                {
                    featureBuffer.set_Value(fieldindex2, gb);
                }
   
                featureCursor.InsertFeature(featureBuffer);
                featureCursor.Flush();
                System.Runtime.InteropServices.Marshal.ReleaseComObject(featureCursor);
                index++;
            }
        }

        //将传入的List<IPolylne>中的多条线要素进行合并为一条线要素
        public IFeature UnionCurrentLineList(List<IFeature> currentMergeLineList)
        {
            IFeatureLayer featureLayer = map.get_Layer(1) as IFeatureLayer;
            IFeatureClass featureClass = featureLayer.FeatureClass;
           
            ITopologicalOperator2 pTopologicalOperator;
            IFeature pFeatureTemp = currentMergeLineList[0];
            IGeometry pGeometry = pFeatureTemp.Shape;
            int i = 1;
            while (i < currentMergeLineList.Count)
            {
                pTopologicalOperator = pGeometry as ITopologicalOperator2;
                //ITopologicalOperator的操作是bug很多的,先强制的检查下面三个步骤,再进行操作
                //modifiy in 2016/03/20 12:47
                pTopologicalOperator.IsKnownSimple_2 = false;
                pTopologicalOperator.Simplify();
                pGeometry.SnapToSpatialReference();

                pGeometry = currentMergeLineList[i].Shape;
                pGeometry = pTopologicalOperator.Union(pGeometry);
                i++;
            }
            IFeature unionLine = featureClass.CreateFeature();
            unionLine.Shape = pGeometry;
            IDataset pDataset = featureClass as IDataset;
            pDataset.Workspace.ExecuteSQL("delete from " + featureClass.AliasName + " where SHAPE_Length = 0" );
            return unionLine;
        }
              
        protected override void OnUpdate()
        {
            Enabled = ArcMap.Application != null;
        }
    }

 

 

 

 

 

 

 

  • 0
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小薛引路

喜欢的读者,可以打赏鼓励一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值