ARCGIS engine 定长且批量绘制线段的中垂线

            由于研究的需要,本人需要将一段曲线按等距离打断,分成固定长度的线段,并且按需要的长度绘制线段的中垂线。按照能不自己动手就坚决不动手的原则,我查阅了ARCGIS关于处理线要素的工具,发现只有等距离打断曲线的工具,但没有绘制线段中垂线的工具。哎,无奈之下,只能自己编写程序了。写程序前,先弄明白绘制中垂线的基本流程。实现工具:visual studio 2010+ARCGIS engine10.1 。数据:等距离打断的曲线图层。依据当前的工具和数据,我制定了完成任务的基本流程:

 

          AE加载矢量数据的方法——获取线段的端点(有些线段可能是曲线,因此计算的是线段两点连线的中垂线,我是没想出其他好的方法。)——计算中垂线的两点(由于要求中垂线是定长的,我选择了以线段两点中点为准,求出定长中垂线上另一点)——要素编辑并存储——完成

 

         看了下流程,难点在于计算中垂线的两点:本人选择了一种笨方法,方程求解。基本过程如下:1 利用已知线段的两个端点,求出线段中点的坐标,这个很简单。 2 求出线段端点连线的斜率,中垂线的斜率也就出来了,利用中点就可以求出中垂线的线性表达式,然后结合两点距离公式算出定长点的坐标(有两个点哦,我选择了这两个点来绘制中垂线的)

        基本思路如上,下面就是贴代码时间了:首先贴出核心代码——计算中垂线的两点的函数

 

 

  /// <summary>
        /// 依据输入两点来计算输入两点的中位线的两点
        /// </summary>
        /// <param name="inpoint1"></param>
        /// <param name="inpoint2"></param>
        /// <param name="outpoint1"></param>
        /// <param name="outpoint2"></param>
        private void CaculateMiddleLinePoints(IPoint inpoint1,IPoint inpoint2,out IPoint outpoint1,out IPoint  outpoint2)
        { 
            //k
            double k = (inpoint2.Y - inpoint1.Y) / (inpoint2.X - inpoint1.X);
            //middle point for inpoint1 and inpoint2
            IPoint middlePoint = new PointClass();
            middlePoint.X = (inpoint1.X + inpoint2.X) / 2;
            middlePoint.Y = (inpoint1.Y + inpoint2.Y) / 2;
            double k01=-1/k;
            double b01 = middlePoint.Y -k01 * middlePoint.X;
            //caculate another point of middle line

            //
            double b1 =2*(-middlePoint.X + k01 * b01- k01 * middlePoint.Y);
            double a1 = 1 + k01 * k01;
            // 其中最后的一个数值5000代表的是中点到另一个点的距离,可以依据自己的需求来设置,我直接写成了5000m
            double c1 = middlePoint.X * middlePoint.X + b01 * b01-2 * b01 * middlePoint.Y + middlePoint.Y * middlePoint.Y - 5000 * 5000;
            //到中点距离为5000的有两个点,
            IPoint p1 = new PointClass();
            IPoint p2 = new PointClass();
            
            //如果无解则退出
            double delta=b1 * b1 - 4 * a1 * c1;
            if (delta < 0)
            {
                
                outpoint1 = null;
                outpoint2 = null;
                return;
            }
            p1.X = (-b1 + Math.Sqrt(delta )) / (2 * a1);
            p1.Y = k01 * p1.X + b01;

            p2.X = (-b1 - Math.Sqrt(delta)) / (2 * a1);
            p2.Y = k01 * p2.X + b01;

            //
            outpoint1 = p1;
            outpoint2 = p2;
          
        }

                计算出了中垂线的两点,下面就简单了,就是添加要素的过程,具体如下:

 

 

 private void button2_Click(object sender, EventArgs e)
        {
            button2.Enabled = false;
            //获取存储中位线的shp存储文件
            string targetLayerPath = @"d:\data\";
            string filename = "MiddleLine.shp";
            IWorkspaceFactory myWorkspacefac = new ShapefileWorkspaceFactoryClass();
            IFeatureWorkspace myFeatureworkspace = (IFeatureWorkspace)myWorkspacefac.OpenFromFile(targetLayerPath, 0);
            IFeatureClass targetFeatureclass = myFeatureworkspace.OpenFeatureClass(filename);
            //启动编辑
            IWorkspaceEdit workspaceEdit=(targetFeatureclass as IDataset ).Workspace as IWorkspaceEdit;
            workspaceEdit.StartEditing(true);
            workspaceEdit.StartEditOperation();
            //快速查询数据
            IQueryFilter mQueryFilter = new QueryFilterClass();
            IFeatureCursor mFeatureCursor =  lineLayer.Search(mQueryFilter, false);
            IFeature feature = mFeatureCursor.NextFeature();
            //提示处理进度
            Form2 frmTip = new Form2();
            frmTip.Show();
            frmTip.TopMost = true;
            System.Windows.Forms.Application.DoEvents();
            int i = 0;
            int featureCount = lineLayer.FeatureClass.FeatureCount(null);

            while (feature != null)
            {
                IPolyline line = feature.Shape as IPolyline;
                IPoint startPoint = line.FromPoint;
                IPoint endPoint = line.ToPoint;
                //计算中位线的两点坐标
                IPoint sMiPoint=new PointClass();
                IPoint eMIPoint=new PointClass();
                CaculateMiddleLinePoints(startPoint, endPoint,out sMiPoint,out eMIPoint);
                if (sMiPoint == null || eMIPoint == null)
                { 
                    string s=i.ToString();
                    MessageBox.Show(s);
                    return;
                    Application.Exit();
                }
                IPolyline miLine = new PolylineClass();
                miLine.FromPoint = sMiPoint;
                miLine.ToPoint = eMIPoint;
                IFeature addFeature = targetFeatureclass.CreateFeature();
                addFeature.Shape = miLine as IGeometry;
                addFeature.Store();
                //搜索下一要素
                feature = mFeatureCursor.NextFeature();
                 
                //提示处理信息
                i++;
                double leftcount = featureCount - i;
                frmTip.label1.Text = "请稍后,目前还剩 " + leftcount.ToString() + " 个要素未处理!";

            }
            //退出编辑状态
            workspaceEdit.StopEditOperation();
            workspaceEdit.StopEditing(true );
            
            //处理完毕,退出提示
            frmTip.Close();
            frmTip.Dispose();

            button2.Enabled = true;
        }

                哈哈,大功告成了!贴下我的结果图

 

可执行程序已经重新上传,有需要的可自行下载https://download.csdn.net/download/dingzhi816/12325081(刚上传,正审核,有需要可以联系邮箱:dingzhi816@163.com)

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值