ArcEngine环境下合并断开的线要素(根据属性)

1.遇到的问题:

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

2.思路:

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

 3.程序的实现和结果:

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

     4.程序源代码:

  1 using System;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 using System.Text;
  5 using System.IO;
  6 using System.Windows.Forms;
  7 using ESRI.ArcGIS.ArcMapUI;
  8 using ESRI.ArcGIS.Carto;
  9 using ESRI.ArcGIS.Geodatabase;
 10 using ESRI.ArcGIS.Geometry;
 11
 12 namespace MergeDisconnectPolylineAddin
 13 {
 14     public class MergePolyline : ESRI.ArcGIS.Desktop.AddIns.Button
 15     {
 16
 17         IMap map = null;
 18         IActiveView pActiveView = null;
 19         //private List<IPolyline> DisconnPolylineList = new List<IPolyline>();
 20
 21         public MergePolyline()
 22         {
 23             IMxDocument mxDoc = ArcMap.Application.Document as IMxDocument;
 24             map = mxDoc.FocusMap;
 25             pActiveView = mxDoc.ActivatedView;
 26         }
 27
 28         protected override void OnClick()
 29         {
 30             //
 31             //  TODO: Sample code showing how to access button host
 32             //
 33             ArcMap.Application.CurrentTool = null;
 34
 35             //计算程序耗时
 36             DateTime beforDT = System.DateTime.Now;
 37
 38             List<string> distinctString = getDistinctNAMEValue();
 39             MergePloyline(distinctString);
 40
 41             DateTime afterDT = System.DateTime.Now;
 42             TimeSpan ts = afterDT.Subtract(beforDT);
 43             MessageBox.Show("线要素合并结束,运行程序共耗时约:"+ ts.Minutes+"分钟");
 44         }
 45
 46         public List<string> getDistinctNAMEValue()
 47         {
 48             IFeatureLayer featureLayer = map.get_Layer(0) as IFeatureLayer;
 49             IFeatureClass featureClass = featureLayer.FeatureClass;
 50             IQueryFilter queryFilter = new QueryFilterClass();
 51             queryFilter.WhereClause = "";
 52             IFeatureCursor pFeatCursor = featureClass.Search(queryFilter, false);
 53             IFeature pFeature = pFeatCursor.NextFeature();
 54             ArrayList fieldArray = new ArrayList();
 55             List<string> distinctString = new List<string>();
 56             while (pFeature != null)
 57             {
 58                 if (featureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
 59                 {
 60                     IFields fields = pFeatCursor.Fields;
 61                     int fieldIndex = fields.FindField("NAME");
 62                     string field_NAME = (string)pFeature.get_Value(fieldIndex);
 63                     fieldArray.Add(field_NAME);
 64                 }
 65                 pFeature = pFeatCursor.NextFeature();
 66             }
 67             distinctString = removeSameString(fieldArray);
 68             return distinctString;
 69         }
 70
 71         public void MergePloyline(List<string> DistinctNameValue)
 72         {
 73             IFeatureLayer featureLayer = map.get_Layer(0) as IFeatureLayer;
 74             IFeatureClass featureClass = featureLayer.FeatureClass;
 75
 76             //IDataset dataset = featureClass as IDataset;
 77             //IWorkspaceEdit workspaceEdit = dataset.Workspace as IWorkspaceEdit;
 78             //Type.Missing指的是空类型,因为有些方法你传null给它会出错的,必须要用Type.Missing.
 79             object Missing = Type.Missing;
 80             //workspaceEdit.StartEditing(true);
 81             //workspaceEdit.StartEditOperation();
 82             //string field_NAME = "";
 83
 84             for (int i = 0; i < DistinctNameValue.Count; i++)
 85             {
 86                 IQueryFilter queryFilter = new QueryFilterClass();
 87                 queryFilter.WhereClause = "";
 88                 IFeatureCursor pFeatCursor = featureClass.Search(queryFilter, false);
 89                 IFeature pFeature = pFeatCursor.NextFeature();
 90
 91                 IFeature pFeatureFirst = pFeature;
 92                 //List<IPolyline> toMergePolylineList = new List<IPolyline>();
 93
 94                 IGeometryCollection Geometrybag = new GeometryBagClass();
 95                 ITopologicalOperator2 pTopOperatorFirst = null;
 96                 IGeometry geometrySecond = null;
 97                 IGeometry pGeometryFirst = null;
 98                 bool bSwitch = true;
 99                 while (pFeature != null)
100                 {
101                     map.SelectFeature(featureLayer, pFeature);
102                     if (featureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
103                     {
104                         //IPolyline polyline = geometry as IPolyline;
105                         IFields fields = pFeatCursor.Fields;
106                         int fieldIndex = fields.FindField("NAME");
107                         string field_NAME = (string)pFeature.get_Value(fieldIndex);
108
109                         if (field_NAME == DistinctNameValue[i])
110                         {
111                             if (bSwitch)
112                             {
113                                 //将当前name字段相同的feature中的第一个feature传给pFeatureFirst
114                                 pFeatureFirst = pFeature;
115                                 pGeometryFirst = pFeature.Shape;
116                                 pTopOperatorFirst = (ITopologicalOperator2) pGeometryFirst;
117                                 pTopOperatorFirst.IsKnownSimple_2 = false;
118                                 pTopOperatorFirst.Simplify();
119                                 pGeometryFirst.SnapToSpatialReference();
120                                 bSwitch = false;
121                                 //break;
122                             }
123                             else
124                             {
125                                 //geometrySecond = pFeature.ShapeCopy;
126                                 geometrySecond = pFeature.Shape;
127                                 Geometrybag.AddGeometry(geometrySecond, ref Missing, ref Missing);
128                                 //toMergePolylineList.Add(polyline);
129                             }
130                         }
131                         //DisconnPolylineList.Add(polyline);
132                     }
133                     pFeature = pFeatCursor.NextFeature();
134                 }
135                 IEnumGeometry tEnumGeometry = (IEnumGeometry)Geometrybag;
136                 //IGeometry mergeGeomery = null;
137                 pTopOperatorFirst.ConstructUnion(tEnumGeometry);
138
139                 pTopOperatorFirst.IsKnownSimple_2 = false;
140                 pTopOperatorFirst.Simplify();
141                 pFeatureFirst.Shape = pGeometryFirst;
142                 //pFeatureFirst.Store();
143                 IFeatureLayer featureLayer2 = map.get_Layer(1) as IFeatureLayer;
144                 IFeatureClass featureClass2 = featureLayer2.FeatureClass;
145                 AddPolyline(featureClass2, pGeometryFirst);
146             }
147             //workspaceEdit.StopEditOperation();
148             //workspaceEdit.StopEditing(true);
149         }
150         private void AddPolyline(IFeatureClass pFeatureClass, IGeometry polyline)
151         {
152             IFeatureBuffer featureBuffer = pFeatureClass.CreateFeatureBuffer();
153             IFeatureCursor featureCursor;
154             featureCursor = pFeatureClass.Insert(true);
155             featureBuffer.Shape = polyline;
156             featureCursor.InsertFeature(featureBuffer);
157             featureCursor.Flush();
158             System.Runtime.InteropServices.Marshal.ReleaseComObject(featureCursor);
159         }
160         public List<string> removeSameString(ArrayList stringArray)
161         {
162             //List用于存储从数组里取出来的不相同的元素
163             List<string> distinctString = new List<string>();
164             foreach (string eachString in stringArray)
165             {
166                 if (!distinctString.Contains(eachString))
167                     distinctString.Add(eachString);
168             }
169             return distinctString;
170         }
171
172         protected override void OnUpdate()
173         {
174             Enabled = ArcMap.Application != null;
175         }
176     }
177
178 }

    5.总结

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

时间: 2024-08-05 15:07:58

ArcEngine环境下合并断开的线要素(根据属性)的相关文章

【应用笔记】【AN003】VC++环境下基于以太网的4-20mA电流采集

简介 4-20mA电流环具有广泛的应用前景,在许多行业中都发挥着重要作用.本文主要介绍了以太网接口的4-20mA电流采集模块在VC++环境下进行温度采集,实现WINDOWS平台对数据的采集.分析及显示. 系统组成及工作原理 系统组成主要包括PT100铂电阻.SBWZ温度变送器.4-20mA电流采集模块(GM4008)以及上位机软件组成,如图1所示. PT100铂电阻温度传感器:利用铂金属阻值随温度的变化而变化的特性制成的一种温度传感器,主要用来测量温度的变化量. SBWZ温度变送器:一种现场安装

第一部分:使用iReport制作报表的详细过程(Windows环境下)

提示:在有些板块,文中的图片看不到,建议到我的blog浏览文章:http://blog.csdn.net/jemlee2002/文章将会涉及3个方面的内容: 第二部分:使用Jasperreport作为报表控件开发胖客户端报表应用 第三部分:使用Jasperreport作为报表控件开发Web报表应用 1.前言 在网络上可以搜索到很多使用iReport和Jasperreport配合实现各种报表任务的文章,但是我觉得很少有一篇(几乎没有)做一个比较详细的介绍如何使用iReport制作报表的全过程,我所

线要素的节点提取

首先我并不清楚是不是还有比这种方法更好的方法,但是由于项目需要只能暂时使用这个了,而且感觉还不错. 上篇中提到已经将线要素在折点处断开,是为了在空间分析中数据更加合理,但归根到底我们最后需要检索并分析的是节点数据,也就是管道的接口或阀门.所以接下来的工作就是提取节点.我用的方法是对断开的(不断开也可以)线要素创建网络数据集,这也是之前先把数据存入数据库的原因. 创建网络数据集都知道要先创建地理数据库,然后要素集,最后将线要素导入到要素集中并在要素集下创建网络数据集,这样就会得到一个**_ND_J

redis持久化策略梳理及主从环境下的策略调整记录

redis是一个内存数据库,它的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称为"半持久化模式"):也可以把每一次数据变化都写入到一个Append Only File(AOF)里面(这称为"完全持久化模式").redis提供了两种不同级别的持久化方式:一种是默认的RDB(filesnapshotting快照)持久化,一种是AOF持久化,这两种持久化方式都可以将内存中的数据库状态保存到磁盘上,但是原理非常不同,区别很明显! 1.RDB持久化可以在

【应用笔记】【AN004】VB环境下基于RS-485的4-20mA电流采集

版本:第一版作者:周新稳 杨帅 日期:20160226 =========================== 本资料高清PDF 下载: http://pan.baidu.com/s/1c1uuhLQ 源代码包下载: http://pan.baidu.com/s/1LSuXw =========================== 简介 本应用笔记主要说明如何在VB开发环境下基于RS485实现4-20mA电流采集. 系统组成及工作原理 系统组成如图1所示,主要包括 PT100铂电阻温度传感器.S

在vs 2015环境下,c语言和汇编混编操作简析(更新中......)

在VS 2015环境下如何混编. 在新建工程里也会发现了很多问题, 应用程序类型分为:windows应用程序,控制台应用程序,DLL,静态库 静态库: 静态库是指在我们的应用中,有一些公共代码是需要反复使用,就把这些代码编译为"库"文件:在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中的这种库. 程序编译一般需经预处理.编译.汇编和链接几个步骤.静态库特点是可执行文件中包含了库代码的一份完整拷贝:缺点就是被多次使用就会有多份冗余拷贝. 静态库和动态库是两种共享程序

mosquitto在Linux环境下的部署/安装/使用/测试

mosquitto在Linux环境下的部署 看了有三四天的的源码,(当然没怎么好好看了),突然发现对mosquitto的源码有了一点点感觉,于是在第五天决定在Linux环境下部署mosquitto. 使用传统源码安装步骤: 步骤1:http://mosquitto.org/files/source/官网下载源码,放到Linux环境中.解压后,找到主要配置文件config.mk,其中包含mosquitto的安装选项,需要注意的是,默认情况下mosquitto的安装需要OpenSSL(一个强大的安全

linux 环境下 mysql 导出CSV格式报表

一般情况下不会特意到linux系统上去使用mysql, 毕竟没有类似MysqlFront这样现成的操作工具.但是产品的线上服务器是linux服务器,没办法,只能硬着头皮码shell语句来操作了. 通用语句如下: mysql -u biadmin -h lbw-52xfj.mysql.rds.aliyuncs.com -p -e "你需要的sql语句" > 文件输出位置 -u 是mysql用户名, -h 是主机地址(如果是在本机上操作可以写 "localhost"

项目:一次测试环境下的高可用NFS文件服务器(DRBD+heartbeat+NFS)

什么是DRBD? 分布式复制块设备.当你将数据写入本地的DRBD设备上的文件系统时,数据同时会被发送到远程端的另一边的DRBD设备文件系统里,保障数据实时同步,当本地的DRBD设备突然故障,远程节点还保留一份一模一样的数据,根据这个特性,可以结合heatbeat的ha开源软件,实现高可用! 我们都把DRBD理解是网络raid1磁盘阵列. DRBD底层设备可以是 1)一块磁盘,或者一个分区. 2)raid设备. 3)逻辑卷lvm. 4)任何块设备. DRBD支持三种不同的复制协议.协议A,协议B,