ArcEngine利用点打断线的算法思路

最近一个师妹在做城市可达性分析的相关研究,在对原始数据处理的时候需要利用点打断线。本人第一时间想到的是ArcToolbox里的在点处分割线这一工具,奈何最终没有实现(PS:也有可能是因为我设置的参数不对~),于是还是考虑利用ArcEngine来做,下面说一下我的解决思路!先来看一种最简单的情况:
在这里插入图片描述这种是最简单的情况,一点与一线相交,打断的时候利用IFeatureEdit接口的Split方法即可分割,代码如下:

        private void Split(IFeature pPolylineFeature, IPoint pPoint)
        {
            IFeatureEdit pFeatureEdit = pPolylineFeature as IFeatureEdit;
            pFeatureEdit.Split(pPoint);
        }

以上代码即可完成利用一个点对一条线进行打断的功能。但在实际情况下还需要考虑三种情况。
第一:必须要找出与线要素相交的点(PS:不相交当然无法打断)。
第二:与一条线相交的点不一定只有一个,可能有很多个点。
第三:如果有很多的点与一条线相交,这些点中还包括与线要素首尾端点重合的点,那么还必须排除掉这条线的首尾端点。
下面看另一种情况:
在这里插入图片描述
在上图中,线段ABC表示一条要素记录,线段CE表示一条要素记录,它们相交于C点,D点为CE上的一点。按照上面的条件,如果用这5个点对线要素进行打断,那么最终的结果应该是AB、BC、CD、DE,实际上就是利用B打断ABC,D打断CE。A、C、E因为是两条线要素的端点,因此不参与打断。整个过程为:遍历点要素,若该点与部分线要素相交,则获取这些线要素。然后遍历这些线要素,如果其端点与点要素相同则跳出循环,否则进行打断。其代码如下:

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 WindowsFormsApplication1
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }

        // 打断线
        private void btnSplit_Click(object sender, EventArgs e)
        {
            IFeatureClass pPointFeatureClass = GetFeatureClass(@"C:\Users\DSF\Desktop\data\point.shp");
            IFeatureClass pPolylineFeatureClass = GetFeatureClass(@"C:\Users\DSF\Desktop\data\line.shp");
            SplitByPoints(pPointFeatureClass, pPolylineFeatureClass);
        }

        // 获取要素类
        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.GetFileNameWithoutExtension(filePath));
            return pFeatureClass;
        }

        // 点处分割线
        private void SplitByPoints(IFeatureClass pPointFeatureClass, IFeatureClass pPolylineFeatureClass)
        {
            IFeatureCursor pPointFeatureCursor = pPointFeatureClass.Search(null, true);
            IFeature pPointFeature = pPointFeatureCursor.NextFeature();
            if (pPointFeature == null)
            {
                return;
            }

            // 创建空间查询器
            ISpatialFilter pSpatialFilter = new SpatialFilter();
            pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIndexIntersects;
            pSpatialFilter.GeometryField = "Shape";

            // 遍历点要素
            while (pPointFeature != null)
            {
                pSpatialFilter.Geometry = pPointFeature.ShapeCopy;

                // 线要素游标
                IFeatureCursor pPolylineFeatureCursor = pPolylineFeatureClass.Search(pSpatialFilter, false);
                IFeature pPolylineFeature = pPolylineFeatureCursor.NextFeature();
                if (pPolylineFeature == null)
                {
                    continue;
                }

                // 遍历线要素
                while (pPolylineFeature != null)
                {
                    IRelationalOperator pRelationalOperator = pPointFeature.ShapeCopy as IRelationalOperator;
                    IPolyline pPolyline = pPolylineFeature.ShapeCopy as IPolyline;
                    if (pRelationalOperator.Equals(pPolyline.FromPoint) || pRelationalOperator.Equals(pPolyline.ToPoint))
                    {
                        break;
                    }
                    else
                    {
                        IFeatureEdit pPolylineFeatureEdit = pPolylineFeature as IFeatureEdit;
                        pPolylineFeatureEdit.Split(pPointFeature.ShapeCopy);
                        pPolylineFeature = pPolylineFeatureCursor.NextFeature();
                    }
                }

                // 进度+1
                Marshal.ReleaseComObject(pPolylineFeatureCursor);
                pPointFeature = pPointFeatureCursor.NextFeature();
                
            }
            Marshal.ReleaseComObject(pPointFeatureCursor);
        }
    }
}

最终结果如图所示:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值