1、前言
本文介绍ArcEngine
中要素合并的实现方法。
2、要素的合并
要素合并的代码如下:
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using System;
using System.Windows.Forms;
namespace App
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
// 合并
private void btnMerge_Click(object sender, EventArgs e)
{
IFeatureClass pFeatureClass = GetFeatureClass(@"C:\Users\DSF\Desktop\data\polygon.shp");
IGeometry pGeometry = GetMergeGeometry(pFeatureClass);
CreateFeatureClass(pGeometry, @"C:\Users\DSF\Desktop\data\merge.shp");
}
// 获取要素类
private IFeatureClass GetFeatureClass(string filePath)
{
IWorkspaceFactory pWorkspaceFactory = new ShapefileWorkspaceFactory();
IWorkspaceFactoryLockControl pWorkspaceFactoryLockControl = pWorkspaceFactory as IWorkspaceFactoryLockControl;
if (pWorkspaceFactoryLockControl.SchemaLockingEnabled)
{
pWorkspaceFactoryLockControl.DisableSchemaLocking();
}
IWorkspace pWorkspace = pWorkspaceFactory.OpenFromFile(System.IO.Path.GetDirectoryName(filePath), 0);
IFeatureWorkspace pFeatureWorkspace = pWorkspace as IFeatureWorkspace;
IFeatureClass pFeatureClass = pFeatureWorkspace.OpenFeatureClass(System.IO.Path.GetFileName(filePath));
return pFeatureClass;
}
// 合并几何体
private IGeometry GetMergeGeometry(IFeatureClass pFeatureClass)
{
IGeoDataset pGeoDataset = pFeatureClass as IGeoDataset;
ISpatialReference pSpatialReference = pGeoDataset.SpatialReference;
// 创建集合
IGeometryBag pGeometryBag = new GeometryBag() as IGeometryBag;
pGeometryBag.SpatialReference = pSpatialReference;
IGeometryCollection pGeometryCollection = pGeometryBag as IGeometryCollection;
// 属性过滤
IQueryFilter pQueryFilter = new QueryFilter();
pQueryFilter.AddField("Shape");
// 要素游标
IFeatureCursor pFeatureCursor = pFeatureClass.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();
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(pFeatureCursor);
// 合并要素
ITopologicalOperator pTopologicalOperator = null;
if (pFeatureClass.ShapeType == esriGeometryType.esriGeometryPoint)
{
pTopologicalOperator = new Multipoint() as ITopologicalOperator;
pTopologicalOperator.ConstructUnion(pGeometryCollection as IEnumGeometry);
}
else if (pFeatureClass.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;
}
// 创建要素类
private IFeatureClass CreateFeatureClass(IGeometry pGeometry, string filePath)
{
IGeometryDef pGeometryDef = new GeometryDef();
IGeometryDefEdit pGeometryDefEdit = pGeometryDef as IGeometryDefEdit;
if (pGeometry.GeometryType == esriGeometryType.esriGeometryMultipoint)
{
pGeometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryMultipoint;
pGeometryDefEdit.HasM_2 = false;
pGeometryDefEdit.HasZ_2 = false;
pGeometryDefEdit.SpatialReference_2 = pGeometry.SpatialReference;
}
else if (pGeometry.GeometryType == esriGeometryType.esriGeometryPolyline)
{
pGeometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolyline;
pGeometryDefEdit.HasM_2 = false;
pGeometryDefEdit.HasZ_2 = false;
pGeometryDefEdit.SpatialReference_2 = pGeometry.SpatialReference;
}
else
{
pGeometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolygon;
pGeometryDefEdit.HasM_2 = false;
pGeometryDefEdit.HasZ_2 = false;
pGeometryDefEdit.SpatialReference_2 = pGeometry.SpatialReference;
}
// 字段集合
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 = pGeometry;
pFeatureCursor.InsertFeature(pFeatureBuffer);
pFeatureCursor.Flush();
return pFeatureClass;
}
}
}
初始数据如下图:
合并后的数据如下图:
3、结语
如果数据量较大,应考虑使用ITopologicalOperator
接口的ConstructUnion
方法,同时使用IFeatureBuffer
实现要素的插入。