ArcEngine 将管线属性表里面写入管点

现有管线数据,需要生成管点数据,然后在管线的属性表里面写入起始管点和终止管点。

      思路:在ArcMap中用管线数据新建一个网络数据集就会自动生成管点数据,然后通过AE编程将每个管线(Polyline)的起始点(FromPoint)和终止点(ToPoint)通过缓冲区(Buffer)在管点图层中找到对应的点,然后将管点编号写入到管线的属性表中。

     数据准备好后,现在开始写代码了:

     这里的管线数据因为是CAD数据,数据质量不是很好,有的管线重复了,这样生成管点的时候也就有重复的,所以这里需要把管点图层中重复的管点删除掉


private void Bt_WritePoint_Click(object sender, EventArgs e) { WritePipeLine(); MessageBox.Show("写入成功!"); } private void WritePipeLine() { int a =0; try { ILayer pLayer = axMapControl1.get_Layer(1);//管线图层 IFeatureLayer pFeatureLayer = pLayer as IFeatureLayer; IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass; IFeatureCursor pFeatureCursor = pFeatureClass.Search(null, false); IFeature pFeature = pFeatureCursor.NextFeature(); progressBar1.Maximum = pFeatureClass.FeatureCount(null)+100; while (pFeature != null) { a++; if (a % 10 == 0) //处理10条数据进度条显示一次 { progressBar1.Value += progressBar1.Step;//进度条提示 label1.Text = a.ToString(); Application.DoEvents(); } if (pFeature.Shape != null) { if (pFeature.Shape.GeometryType == esriGeometryType.esriGeometryPolyline) { WritePloyline(pFeature); } } pFeature = pFeatureCursor.NextFeature(); } } catch (Exception ex) { MessageBox.Show(ex.Message); MessageBox.Show(a.ToString()); } } private void WritePloyline(IFeature pFeature) { if (pFeature.Shape is Polyline) { IPolyline pPolyline = pFeature.Shape as IPolyline; DeleteRedLinePoint(pPolyline.FromPoint); DeleteRedLinePoint(pPolyline.ToPoint); } } //删除重复的管点 IFeatureClass pFeatureClass = null; private void DeleteRedLinePoint(IPoint pPoint) { ITopologicalOperator pTopologicalOperator = pPoint as ITopologicalOperator; IGeometry pGeometry = pTopologicalOperator.Buffer(0);//Distence是缓冲距离 pTopologicalOperator.Simplify(); ISpatialFilter pSpatialfilter = new SpatialFilterClass(); pSpatialfilter.Geometry = pGeometry; pSpatialfilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains; if (pFeatureClass == null) { ILayer pLayer = axMapControl1.get_Layer(0); string name = pLayer.Name; IFeatureLayer pFeatureLayer = pLayer as IFeatureLayer; pFeatureClass = pFeatureLayer.FeatureClass; } IFeatureCursor FeatureCursors = pFeatureClass.Search(pSpatialfilter, false); IFeature Feature = FeatureCursors.NextFeature(); // //删除重复要素 int a = 0;//查找的要素个数 while (Feature != null) { IPoint point = Feature.Shape as IPoint; if ( point.X == pPoint.X && point.Y==pPoint.Y) { a++; if (a > 1) { Feature.Delete(); FeatureCursors.Flush();//将缓存写入到数据库中 } } Feature = FeatureCursors.NextFeature(); } System.Runtime.InteropServices.Marshal.ReleaseComObject(FeatureCursors);//释放资源 }
管点数据处理完之后然后开始往管线属性表里面写入管点信息。
       private void Bt_WritePoint_Click(object sender, EventArgs e)
        {
            WritePipeLine();
            MessageBox.Show("写入成功!");
        }
        private void WritePipeLine()
        {
            int a = 0;
            try
            {
                ILayer pLayer = axMapControl1.get_Layer(1);//管线图层
                IFeatureLayer pFeatureLayer = pLayer as IFeatureLayer;
                IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;
                IFeatureCursor pFeatureCursor = pFeatureClass.Search(null, false);
                IFeature pFeature = pFeatureCursor.NextFeature();
                progressBar1.Maximum = pFeatureClass.FeatureCount(null)+100;
                while (pFeature != null)
                {
                    a++;
                    if (pFeature.Shape.GeometryType == esriGeometryType.esriGeometryPolyline)
                    {
                        WritePloyline(pFeature);
                    }
                    pFeature.Store();

                    if (a % 20 == 0) //达到20个要素保存一次
                    {
                        
                        progressBar1.Value += progressBar1.Step;//执行步长
                        label1.Text = a.ToString();
                        Application.DoEvents();
                    }
                    pFeature = pFeatureCursor.NextFeature();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                MessageBox.Show(a.ToString());
            }
        }
        //写入起始管点和终止管点编号
        private void WritePloyline(IFeature pFeature)
        {
            if (pFeature.Shape is Polyline)
            {
                IPolyline pPolyline = pFeature.Shape as IPolyline;
                string name = pFeature.OID.ToString();
               string FNID1= ReturnLinePoint(pPolyline.FromPoint);
                   if (FNID1 == "")
                   {

                       pFeature.set_Value(5, "-1");
                   }
                   else
                   {
                       pFeature.set_Value(5, FNID1);
                   }
               string FNID2= ReturnLinePoint(pPolyline.ToPoint);
               if (FNID2 == "")
               {

                   pFeature.set_Value(6, "-1");
               }
               else
               {
                   pFeature.set_Value(6, FNID2);
               }
            }
        }
        //返回该节点最近的管点
        IFeatureClass pFeatureClass = null;
        private string  ReturnLinePoint(IPoint pPoint)
        {
            ITopologicalOperator pTopologicalOperator = pPoint as ITopologicalOperator;
           IGeometry  pGeometry = pTopologicalOperator.Buffer(0);//Distence是缓冲距离
           pTopologicalOperator.Simplify();
           ISpatialFilter pSpatialfilter = new SpatialFilterClass();
           pSpatialfilter.Geometry = pGeometry;
           pSpatialfilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;
           if (pFeatureClass == null)
           {
               ILayer pLayer = axMapControl1.get_Layer(0);
               string name = pLayer.Name;
               IFeatureLayer pFeatureLayer = pLayer as IFeatureLayer;
                pFeatureClass = pFeatureLayer.FeatureClass;
           }
           IFeatureCursor FeatureCursors = pFeatureClass.Search(pSpatialfilter, false);
           IFeature Feature = FeatureCursors.NextFeature();
           while (Feature != null)
           {
                   IPoint point = Feature.Shape as IPoint;
                   if (point.X == pPoint.X && point.Y ==pPoint.Y)
                   {
                       System.Runtime.InteropServices.Marshal.ReleaseComObject(FeatureCursors);//释放资源
                       return Feature.get_Value(2).ToString();
                   }
                   Feature = FeatureCursors.NextFeature();
           }
           System.Runtime.InteropServices.Marshal.ReleaseComObject(FeatureCursors);//释放资源
           return "";
        }

处理完数据之后如下图:

总结:

1、修改数据的时候,修改属性表保存用 pFeature.Store();修改要素的几何形状保存用FeatureCursors.Flush();Fush()使用的时候,如果一个游标里面的修改要素比较多,达到300个需要Flush一次。

2、在点缓冲查找同一坐标的点时给出过滤条件出现问题:  pSpatialfilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelEnvelopeIntersects;这个是两个要素的包络线(Envelope)是否相交,而不是包含,所以查不到想要的管点,应该是 pSpatialfilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;这个是包含关系。

3、在处理数据的时候,处理的很慢大概速度是1.5s/个。主要时间花在 IFeature Feature = FeatureCursors.NextFeature()。

4、打开游标的时候记得释放游标: System.Runtime.InteropServices.Marshal.ReleaseComObject(FeatureCursors)。

5、mdb数据库中的默认字段比shp文件里面的多一个Shape字段,在获取或修改要素的字段值时注意填入的索引。

6、之前在寻找相同点时候只有判断point.X == pPoint.X ,导致删除了很多有用的点,浪费了一晚上的时间(处理数据比较慢)。原因是管点的密集程度比较高,很多管点的X坐标是相同的,这会导致删除了其他有用的管点。所以应该加上point.Y ==pPoint.Y。

7、由于是CAD数据,数据的质量不高,有很多管线的长度为0,这个地方前期没有做处理,所以后期浪费了很多的处理时间。

 

 

posted on 2015-09-21 00:02  Geography爱好者  阅读(462)  评论(0)    收藏  举报

导航