1.遇到的问题:

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

2.思路:

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

 3.程序的实现和结果:

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

     4.程序源代码:

 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() 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() 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 = ; 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() 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;
}
} }

    5.总结

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

-------------------------------------------------------------------------------------------------------------------------

本文系作者GISQZC原创文章,欢迎转载,但必须注明出处,否则将追究相关法律责任!

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

  1. ArcEngine中合并断开的线要素(根据几何判断)

    在上一篇ArcEngine环境下合并断开的线要素(根据属性)随笔中介绍了如何通过shp文件属性表中相同的属性字段进行线要素的合并.今天刚把通过几何条件判断的方式连接断开的线要素的ArcGIS 插件完成 ...

  2. ArcGIS Engine环境下创建自定义的ArcToolbox Geoprocessing工具

    在上一篇日志中介绍了自己通过几何的方法合并断开的线要素的ArcGIS插件式的应用程序.但是后来考虑到插件式的程序的配置和使用比较繁琐,也没有比较好的错误处理机制,于是我就把之前的程序封装成一个类似于A ...

  3. 在windows环境下部署nuxt项目(线上发布部署)

    因为公司项目需要兼容SEO,同时我们也一直希望能够真正的实现前后端分离,于是毫不犹豫的选择了nuxt. 话说要重构前后端分离真是一个大工程,由于各种原因我们团队花了近两年时间都没有完成,最近才又重启把 ...

  4. XCode5环境下利用crash log调试线上Crash的流程

    1.前言 本文主要介绍在XCode5环境下,如何根据App自己生成的crashlog来调试真机上运行时产生的crash问题. 2. 步骤 (1)构造一段会crash的代码,并放到viewDidLoad ...

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

    提示:在有些板块,文中的图片看不到,建议到我的blog浏览文章:http://blog.csdn.net/jemlee2002/文章将会涉及3个方面的内容: 第一部分:使用iReport制作报表的详细 ...

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

    版本:第一版作者:周新稳 杨帅 日期:20160226 =========================== 本资料高清PDF 下载: http://pan.baidu.com/s/1c1uuhLQ ...

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

    简介 4-20mA电流环具有广泛的应用前景,在许多行业中都发挥着重要作用.本文主要介绍了以太网接口的4-20mA电流采集模块在VC++环境下进行温度采集,实现WINDOWS平台对数据的采集.分析及显示 ...

  8. 【应用笔记】【AN001】VC#开发环境下基于以太网的4-20mA电流采集(基于modbus tcp 协议)

    版本:第一版 作者:毛鹏 杨帅 日期:20151108 简介 4-20mA电流环具有广泛的应用前景,在许多行业中都发挥着重要作用.本文主要介绍了以太网接口的4-20mA电流采集模块在VC#环境下进行温 ...

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

    redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到磁盘来保证持久化.可以不定期的通过异步方式保存到磁盘上(即“半持久化模式”):也可以把每一次数据变化都写入到一个A ...

随机推荐

  1. [转]Android dex分包方案

    转载自:https://m.oschina.net/blog/308583 当一个app的功能越来越复杂,代码量越来越多,也许有一天便会突然遇到下列现象: 1. 生成的apk在2.3以前的机器无法安装 ...

  2. C# 128位AES 加密解密 (转)

    /// AES加密 2         /// </summary> 3         /// <param name="inputdata">输入的数据 ...

  3. java框架篇---spring AOP 实现原理

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...

  4. MyBatis知多少(25)动态SQL

    使用动态查询是MyBatis一个非常强大的功能.有时你已经改变WHERE子句条件的基础上你的参数对象的状态.在这种情况下的MyBatis提供了一组可以映射语句中使用,以提高SQL语句的重用性和灵活性的 ...

  5. DDD:群里关于验证的结论

    @汤雪华 验证是为了让数据符合要求.各个层的验证是为了确保传递给各个层的数据符合当前层所需要的数据的要求. @小学僧 db model的验证主要是为了保证数据完整. domain model的验证主要 ...

  6. 工作流数据库表设计-ASP.NET

    公司准备开发一套工作流引擎,以前没有什么OA开发经验,也是第一次设计工作流引擎,我把我的一些思路分享一下,希望得到些帮助或者能帮助到一些人. 产品的定位: 1.能够做到前后端分离 2.可以做到项目的分 ...

  7. C#中引用类型和值类型

    C#的值类型包括:结构体(数值类型,bool型,用户定义的结构体),枚举,可空类型. C#的引用类型包括:数组,用户定义的类.接口.委托,object,字符串. 值类型和引用类型的区别在于,值类型的变 ...

  8. .Net魔法堂:史上最全的ActiveX开发教程——发布篇

    一. 前言 接着上一篇<.Net魔法堂:史上最全的ActiveX开发教程——开发篇>,本篇讲述如何发布我们的ActiveX. 二.废话少讲,马上看步骤! 1. 打包  C#开发的Activ ...

  9. Gradle学习系列之八——构建多个Project

    在本系列的上篇文章中,我们讲到了Gradle的依赖管理,在本篇文章中,我们将讲到如何构建多个Project. 请通过以下方式下载本系列文章的Github示例代码: git clone https:// ...

  10. sprint 1 总结

    1.之前已经总结了一下了.. 提前完成了任务,明天还要继续测试一下,看有没有BUG.这次搭建,遇到好多问题,服务器经常不稳定崩毁,毕竟免费...不能完美..途中经常小细节没注意,导致错误连连,卡了好几 ...