开发环境:VS 2013 + ArcEngine 10.4
实现如下效果:
具体代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
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 SplitPolygonTool
{
/// <summary>
/// 面要素
/// </summary>
private string in_PolygonFilePath;
private IFeatureClass in_PolygonFeatureClass;
/// <summary>
/// 空间参考
/// </summary>
private ISpatialReference in_PolygonSpatialReference;
/// <summary>
/// 分割后面要素
/// </summary>
private string out_PolygonFilePath;
private IFeatureClass out_PolygonFeatureClass;
/// <summary>
/// 分割后质心要素
/// </summary>
private string out_PointFilePath;
private IFeatureClass out_PointFeatureClass;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="in_PolygonFilePath"></param>
/// <param name="out_PolygonFilePath"></param>
/// <param name="out_PointFilePath"></param>
public SplitPolygonTool(string in_PolygonFilePath, string out_PolygonFilePath, string out_PointFilePath)
{
this.in_PolygonFilePath = in_PolygonFilePath;
this.in_PolygonFeatureClass = OpenShapefile(in_PolygonFilePath);
this.in_PolygonSpatialReference = GetSpatialReference(in_PolygonFeatureClass);
this.out_PolygonFilePath = out_PolygonFilePath;
this.out_PolygonFeatureClass = CreateShapefile(out_PolygonFilePath, in_PolygonSpatialReference, esriGeometryType.esriGeometryPolygon);
this.out_PointFilePath = out_PointFilePath;
this.out_PointFeatureClass = CreateShapefile(out_PointFilePath, in_PolygonSpatialReference, esriGeometryType.esriGeometryPoint);
}
/// <summary>
/// 创建要素类
/// </summary>
/// <param name="filePath"></param>
/// <param name="pSpatialReference"></param>
/// <param name="geometryType"></param>
/// <returns></returns>
private IFeatureClass CreateShapefile(string filePath, ISpatialReference pSpatialReference, esriGeometryType geometryType)
{
IGeometryDef pGeometryDef = new GeometryDef();
IGeometryDefEdit pGeometryDefEdit = pGeometryDef as IGeometryDefEdit;
pGeometryDefEdit.GeometryType_2 = geometryType;
pGeometryDefEdit.HasM_2 = false;
pGeometryDefEdit.HasZ_2 = false;
pGeometryDefEdit.SpatialReference_2 = pSpatialReference;
// 字段集合
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);
// 创建shp
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", "");
return pFeatureClass;
}
/// <summary>
/// 获取要素类
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
private IFeatureClass OpenShapefile(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;
}
/// <summary>
/// 获取空间参考
/// </summary>
/// <param name="pFeatureClass"></param>
/// <returns></returns>
private ISpatialReference GetSpatialReference(IFeatureClass pFeatureClass)
{
IGeoDataset pGeoDataset = pFeatureClass as IGeoDataset;
ISpatialReference pSpatialReference = pGeoDataset.SpatialReference;
return pSpatialReference;
}
/// <summary>
/// 获取包络框
/// </summary>
/// <param name="pFeature"></param>
/// <returns></returns>
private Tuple<IEnvelope, IEnvelope, IEnvelope, IEnvelope> GetEnvelopeTuple(IFeature pFeature)
{
IEnvelope pEnvelope = pFeature.Shape.Envelope;
double XMin = pEnvelope.XMin;
double YMin = pEnvelope.YMin;
double XMax = pEnvelope.XMax;
double YMax = pEnvelope.YMax;
// 左下
IEnvelope pLeftBottomEnvelope = new Envelope() as IEnvelope;
pLeftBottomEnvelope.XMin = XMin;
pLeftBottomEnvelope.YMin = YMin;
pLeftBottomEnvelope.XMax = XMin + pEnvelope.Width / 2;
pLeftBottomEnvelope.YMax = YMin + pEnvelope.Height / 2;
// 左上
IEnvelope pLeftTopEnvelope = new Envelope() as IEnvelope;
pLeftTopEnvelope.XMin = XMin;
pLeftTopEnvelope.YMin = YMin + pEnvelope.Height / 2;
pLeftTopEnvelope.XMax = XMin + pEnvelope.Width / 2; ;
pLeftTopEnvelope.YMax = YMax;
// 右上
IEnvelope pRightTopEnvelope = new Envelope() as IEnvelope;
pRightTopEnvelope.XMin = XMin + pEnvelope.Width / 2;
pRightTopEnvelope.YMin = YMin + pEnvelope.Height / 2;
pRightTopEnvelope.XMax = XMax;
pRightTopEnvelope.YMax = YMax;
// 右下
IEnvelope pRightBottomEnvelope = new Envelope() as IEnvelope;
pRightBottomEnvelope.XMin = XMin + pEnvelope.Width / 2;
pRightBottomEnvelope.YMin = YMin;
pRightBottomEnvelope.XMax = XMax;
pRightBottomEnvelope.YMax = YMin + pEnvelope.Height / 2;
// 返回
Tuple<IEnvelope, IEnvelope, IEnvelope, IEnvelope> tuple = new Tuple<IEnvelope, IEnvelope, IEnvelope, IEnvelope>(pLeftBottomEnvelope, pLeftTopEnvelope, pRightTopEnvelope, pRightBottomEnvelope);
return tuple;
}
/// <summary>
/// 获取相交部分
/// </summary>
/// <param name="pFeature"></param>
/// <param name="pEnvelope"></param>
/// <returns></returns>
private IGeometry GetIntersectArea(IFeature pFeature, IEnvelope pEnvelope)
{
ITopologicalOperator pTopologicalOperator = pFeature.ShapeCopy as ITopologicalOperator;
IGeometry pGeometry = pTopologicalOperator.Intersect(pEnvelope, esriGeometryDimension.esriGeometry2Dimension);
return pGeometry;
}
/// <summary>
/// 执行工具
/// </summary>
public void ExecuteTool()
{
IFeatureCursor in_PolygonFeatureCursor = in_PolygonFeatureClass.Search(null, true);
IFeature in_PolygonFeature = in_PolygonFeatureCursor.NextFeature();
if (in_PolygonFeature == null)
{
return;
}
// 创建Buffer
IFeatureBuffer out_PolygonFeatureBuffer = out_PolygonFeatureClass.CreateFeatureBuffer();
IFeatureCursor out_PolygonFeatureCursor = out_PolygonFeatureClass.Insert(true);
IFeatureBuffer out_PointFeatureBuffer = out_PointFeatureClass.CreateFeatureBuffer();
IFeatureCursor out_PointFeatureCursor = out_PointFeatureClass.Insert(true);
// 遍历游标
while (in_PolygonFeature != null)
{
Tuple<IEnvelope, IEnvelope, IEnvelope, IEnvelope> tuple = GetEnvelopeTuple(in_PolygonFeature);
// 获取相交区域
IGeometry pLeftBottomArea = GetIntersectArea(in_PolygonFeature, tuple.Item1);
IGeometry pLeftTopArea = GetIntersectArea(in_PolygonFeature, tuple.Item2);
IGeometry pRightTopArea = GetIntersectArea(in_PolygonFeature, tuple.Item3);
IGeometry pRightBottomArea = GetIntersectArea(in_PolygonFeature, tuple.Item4);
// 获取区域质心
IGeometry pLeftBottomCentroid = null;
IGeometry pLeftTopCentroid = null;
IGeometry pRightTopCentroid = null;
IGeometry pRightBottomCentroid = null;
// 插入要素
if (!pLeftBottomArea.IsEmpty)
{
pLeftBottomCentroid = (pLeftBottomArea as IArea).Centroid;
out_PolygonFeatureBuffer.Shape = pLeftBottomArea;
out_PolygonFeatureCursor.InsertFeature(out_PolygonFeatureBuffer);
out_PointFeatureBuffer.Shape = pLeftBottomCentroid;
out_PointFeatureCursor.InsertFeature(out_PointFeatureBuffer);
}
if (!pLeftTopArea.IsEmpty)
{
pLeftTopCentroid = (pLeftTopArea as IArea).Centroid;
out_PolygonFeatureBuffer.Shape = pLeftTopArea;
out_PolygonFeatureCursor.InsertFeature(out_PolygonFeatureBuffer);
out_PointFeatureBuffer.Shape = pLeftTopCentroid;
out_PointFeatureCursor.InsertFeature(out_PointFeatureBuffer);
}
if (!pRightTopArea.IsEmpty)
{
pRightTopCentroid = (pRightTopArea as IArea).Centroid;
out_PolygonFeatureBuffer.Shape = pRightTopArea;
out_PolygonFeatureCursor.InsertFeature(out_PolygonFeatureBuffer);
out_PointFeatureBuffer.Shape = pRightTopCentroid;
out_PointFeatureCursor.InsertFeature(out_PointFeatureBuffer);
}
if (!pRightBottomArea.IsEmpty)
{
pRightBottomCentroid = (pRightBottomArea as IArea).Centroid;
out_PolygonFeatureBuffer.Shape = pRightBottomArea;
out_PolygonFeatureCursor.InsertFeature(out_PolygonFeatureBuffer);
out_PointFeatureBuffer.Shape = pRightBottomCentroid;
out_PointFeatureCursor.InsertFeature(out_PointFeatureBuffer);
}
in_PolygonFeature = in_PolygonFeatureCursor.NextFeature();
}
out_PolygonFeatureCursor.Flush();
out_PointFeatureCursor.Flush();
// 释放游标
Marshal.ReleaseComObject(in_PolygonFeatureCursor);
Marshal.ReleaseComObject(out_PolygonFeatureBuffer);
Marshal.ReleaseComObject(out_PolygonFeatureCursor);
Marshal.ReleaseComObject(out_PointFeatureBuffer);
Marshal.ReleaseComObject(out_PointFeatureCursor);
}
}
}
程序运行结果如下图: