ArcEngine根据Envelope四分多边形

开发环境: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);
        }
    }
}

程序运行结果如下图:
这里写图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值