基于C#的ArcEngine二次开发35:缓冲区分析

目录

0 arcgis建立缓冲区

1 根据选择要素建立缓冲区并查询

1.1 代码

1.2 代码分析

2 从线要素首尾节点相邻的角度合并同名道路


几点说明:

使用ITopologicalOperation.Buffer建立缓冲区时,可能出现以下几种情况:

  • 出现异常卡死现象,修改缓冲区为合适的值,即可解决;
  • 不连续的要素无法建立缓冲区,此时应根据属性判断,将要素分离开来

0 arcgis建立缓冲区

缓冲区是地理空间目标的一种影响范围或服务范围,具体指在点、线、面实体的周围,自动建立的一定宽度的多边。
方法/步骤
1. 向arcmap中添加要建立缓冲区的图层。

基于C#的ArcEngine二次开发35:缓冲区分析_第1张图片

2. 调出建立缓冲区工具。有两种方法可以调出缓冲区工具,一种是在菜单地理处理中选择缓冲区;另外一种方法是在arctoolbox中选择分析工具-邻域分析-缓冲区。

基于C#的ArcEngine二次开发35:缓冲区分析_第2张图片

3. 首先选择输入要素,选择输出要素名字位置和缓冲区范围,融合字段可以根据需要进行设置。
4. 建立缓冲区。线图层建立缓冲区的过程中可以选择缓冲区的位置,在侧类型中可以选择缓冲区在线的左边、右边还是两边都有,末端类型可以选择末端是圆形还是方形,如图,侧类型为full,末端为round形成的缓冲区。

基于C#的ArcEngine二次开发35:缓冲区分析_第3张图片

5. 面建立缓冲区和线一样,不过面的缓冲区侧类型只有两种:full和outside_only。full是对整个面都建立缓冲区,outside_only是在面的外面建立缓冲区。

基于C#的ArcEngine二次开发35:缓冲区分析_第4张图片基于C#的ArcEngine二次开发35:缓冲区分析_第5张图片

6. 在工具箱中右击“缓冲区”可以批处理,节约时间。

基于C#的ArcEngine二次开发35:缓冲区分析_第6张图片             基于C#的ArcEngine二次开发35:缓冲区分析_第7张图片


END
注意事项:融合字段按作图要求进行选择,一般缓冲区都做分析用,可以不要太多属性

1 根据选择要素建立缓冲区并查询

1.1 代码

这是在其他地方找到的一段代码:

实现功能:

1.获取鼠标选中的要素

2.对选中要素设置缓冲距离,在地图上显示缓冲区

3.进行缓冲区查询,获得缓冲区内的要素,并放入TreeList展示

        /// 
        /// 创建缓冲区
        /// 
        private void CreateBuffer()
        {
            ITopologicalOperator pTopo = null;
            IElement pElement = null;
            IGeometry pBuffer = null;
            IGeometry pGeo = null;
            ISelection pSelection = null;
            IEnumFeatureSetup pEnumFeatureSetup = null;
            IEnumFeature pEnumFeature = null;
            IFillSymbol pFillSymbol = null;
            IRgbColor pRgbColor = null;

            IFeature pFea = null;
            IFeature pFeature = null;
            IFeatureLayer pFeaLayer = null;
            IFeatureClass pFeaClass = null;
            IFeatureCursor pFeaCursor = null;

            ISpatialFilter pSpatialfilter = null;

            try
            {
                if (m_pMap != null)
                {
                    (m_pMap as IGraphicsContainer).DeleteAllElements();
                }

                ////    获得选中要素
                pSelection = m_pMap.FeatureSelection;
                pEnumFeatureSetup = pSelection as IEnumFeatureSetup;
                pEnumFeatureSetup.AllFields = true;

                pEnumFeature = pEnumFeatureSetup as IEnumFeature;
                pEnumFeature.Reset();
                pFea = pEnumFeature.Next();

                ////    遍历选中要素
                while (pFea != null)
                {
                    pGeo = pFea.ShapeCopy;
                    pTopo = pGeo as ITopologicalOperator;
                    pBuffer = pTopo.Buffer(m_dDistance);

                    pElement = new PolygonElementClass();
                    pElement.Geometry = pBuffer;

                    ////    设置缓冲区颜色
                    pFillSymbol = new SimpleFillSymbolClass();
                    pRgbColor = new RgbColorClass();
                    pRgbColor.Red = 255;
                    pRgbColor.Green = 255;
                    pRgbColor.Blue = 153;
                    pRgbColor.Transparency = 1;
                    pFillSymbol.Color = pRgbColor;
                    (pElement as IFillShapeElement).Symbol = pFillSymbol;
                    (m_pMap as IGraphicsContainer).AddElement(pElement, 0);

                    ////    设置空间过滤器
                    pSpatialfilter = new SpatialFilterClass();
                    pSpatialfilter.Geometry = pBuffer;

                    ////    遍历图层
                    for (int i = 0; i < m_pMap.LayerCount; i++)
                    {
                        pFeaLayer = m_pMap.get_Layer(i) as IFeatureLayer;
                        pFeaClass = pFeaLayer.FeatureClass;

                        switch (pFeaClass.ShapeType)
                        {
                            case esriGeometryType.esriGeometryPoint:
                                {
                                    pSpatialfilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;
                                    break;
                                }
                            case esriGeometryType.esriGeometryPolyline:
                                {
                                    pSpatialfilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;
                                    break;
                                }
                            case esriGeometryType.esriGeometryPolygon:
                                {
                                    pSpatialfilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;
                                    break;
                                }
                        }

                        pSpatialfilter.GeometryField = pFeaClass.ShapeFieldName;
                        pFeaCursor = pFeaClass.Search(pSpatialfilter, false);
                        pFeature = pFeaCursor.NextFeature();

                        TreeListNode tlNode = null;

                        ////    查询到的要素添加到TreeList
                        while (pFeature != null)
                        {
                            ////    添加图层节点到TreeList
                            bool bIsContainLayer = false;
                            foreach (TreeListNode node in tlResult.Nodes)
                            {
                                if (node.GetDisplayText(0).Equals(pFeaLayer.Name))
                                {
                                    tlNode = node;
                                    bIsContainLayer = true;
                                    break;
                                }
                            }
                            if (!bIsContainLayer)
                            {
                                tlNode = tlResult.AppendNode(new object[] { pFeaLayer.Name }, null);
                            }

                            ////    添加要素到图层节点下
                            bool bIsAdd = false;
                            foreach (TreeListNode childnode in tlNode.Nodes)
                            {
                                if (childnode.GetDisplayText(0).Equals(pFeature.OID.ToString()))
                                {
                                    bIsAdd = true;
                                    break;
                                }
                            }
                            if (!bIsAdd)
                            {
                                tlResult.AppendNode(new object[] { pFeature.OID, GtMap.GxAEHelper.Feature.GetValue(pFeature, "NAME") }, tlNode);
                            }

                            pFeature = pFeaCursor.NextFeature();
                        }
                    }

                    pFea = pEnumFeature.Next();
                }

                IActiveView pActiveView = m_pMap as IActiveView;
                pActiveView.Refresh();

            }
            catch (Exception ex)
            {

            }
        }

 

1.2 代码分析

获取要素图形:

IGeometry pGeo = pFea.ShapeCopy;

将图形要素跳转为ITopologicalOperator接口

ITopologicalOperator pTopo = pGeo as ITopologicalOperator;

在拓扑空间建立缓冲区

IGeometry pBuffer = pTopo.Buffer();

2 从线要素首尾节点相邻的角度合并同名道路

  1 using System;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 using System.Text;
  5 using System.IO;
  6 using System.Windows.Forms;
  7 using ESRI.ArcGIS.ArcMapUI;
  8 using ESRI.ArcGIS.Carto;
  9 using ESRI.ArcGIS.Geodatabase;
 10 using ESRI.ArcGIS.Geometry;
 11 
 12 namespace MergeDisconnectPolylineAddin
 13 {
 14     public class MergePolyline : ESRI.ArcGIS.Desktop.AddIns.Button
 15     {
 16         
 17         IMap map = null;
 18         IActiveView pActiveView = null;
 19         //private List DisconnPolylineList = new List();
 20 
 21         public MergePolyline()
 22         {
 23             IMxDocument mxDoc = ArcMap.Application.Document as IMxDocument;
 24             map = mxDoc.FocusMap;
 25             pActiveView = mxDoc.ActivatedView;
 26         }
 27 
 28         protected override void OnClick()
 29         {
 30             //
 31             //  TODO: Sample code showing how to access button host
 32             //
 33             ArcMap.Application.CurrentTool = null;
 34 
 35             //计算程序耗时
 36             DateTime beforDT = System.DateTime.Now;
 37             
 38             List distinctString = getDistinctNAMEValue();
 39             MergePloyline(distinctString);
 40 
 41             DateTime afterDT = System.DateTime.Now;
 42             TimeSpan ts = afterDT.Subtract(beforDT);
 43             MessageBox.Show("线要素合并结束,运行程序共耗时约:"+ ts.Minutes+"分钟");
 44         }
 45         
 46         public List getDistinctNAMEValue()
 47         {
 48             IFeatureLayer featureLayer = map.get_Layer(0) as IFeatureLayer;
 49             IFeatureClass featureClass = featureLayer.FeatureClass;
 50             IQueryFilter queryFilter = new QueryFilterClass();
 51             queryFilter.WhereClause = "";
 52             IFeatureCursor pFeatCursor = featureClass.Search(queryFilter, false);
 53             IFeature pFeature = pFeatCursor.NextFeature();
 54             ArrayList fieldArray = new ArrayList();
 55             List distinctString = new List();
 56             while (pFeature != null)
 57             {
 58                 if (featureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
 59                 {
 60                     IFields fields = pFeatCursor.Fields;
 61                     int fieldIndex = fields.FindField("NAME");
 62                     string field_NAME = (string)pFeature.get_Value(fieldIndex);
 63                     fieldArray.Add(field_NAME);
 64                 }
 65                 pFeature = pFeatCursor.NextFeature();
 66             }
 67             distinctString = removeSameString(fieldArray);
 68             return distinctString;
 69         }
 70 
 71         public void MergePloyline(List DistinctNameValue)
 72         {
 73             IFeatureLayer featureLayer = map.get_Layer(0) as IFeatureLayer;
 74             IFeatureClass featureClass = featureLayer.FeatureClass;
 75 
 76             //IDataset dataset = featureClass as IDataset;
 77             //IWorkspaceEdit workspaceEdit = dataset.Workspace as IWorkspaceEdit;
 78             //Type.Missing指的是空类型,因为有些方法你传null给它会出错的,必须要用Type.Missing.
 79             object Missing = Type.Missing;
 80             //workspaceEdit.StartEditing(true);
 81             //workspaceEdit.StartEditOperation();
 82             //string field_NAME = "";
 83 
 84             for (int i = 0; i < DistinctNameValue.Count; i++)
 85             {
 86                 IQueryFilter queryFilter = new QueryFilterClass();
 87                 queryFilter.WhereClause = "";
 88                 IFeatureCursor pFeatCursor = featureClass.Search(queryFilter, false);
 89                 IFeature pFeature = pFeatCursor.NextFeature();
 90 
 91                 IFeature pFeatureFirst = pFeature;
 92                 //List toMergePolylineList = new List();
 93 
 94                 IGeometryCollection Geometrybag = new GeometryBagClass();
 95                 ITopologicalOperator2 pTopOperatorFirst = null;
 96                 IGeometry geometrySecond = null;
 97                 IGeometry pGeometryFirst = null;
 98                 bool bSwitch = true;
 99                 while (pFeature != null)
100                 {
101                     map.SelectFeature(featureLayer, pFeature);
102                     if (featureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
103                     {                       
104                         //IPolyline polyline = geometry as IPolyline;
105                         IFields fields = pFeatCursor.Fields;
106                         int fieldIndex = fields.FindField("NAME");
107                         string field_NAME = (string)pFeature.get_Value(fieldIndex);
108                         
109                         if (field_NAME == DistinctNameValue[i])
110                         {
111                             if (bSwitch)
112                             {
113                                 //将当前name字段相同的feature中的第一个feature传给pFeatureFirst
114                                 pFeatureFirst = pFeature;
115                                 pGeometryFirst = pFeature.Shape;
116                                 pTopOperatorFirst = (ITopologicalOperator2) pGeometryFirst;
117                                 pTopOperatorFirst.IsKnownSimple_2 = false;
118                                 pTopOperatorFirst.Simplify();
119                                 pGeometryFirst.SnapToSpatialReference();
120                                 bSwitch = false;
121                                 //break;
122                             }
123                             else
124                             {
125                                 //geometrySecond = pFeature.ShapeCopy;
126                                 geometrySecond = pFeature.Shape;
127                                 Geometrybag.AddGeometry(geometrySecond, ref Missing, ref Missing);
128                                 //toMergePolylineList.Add(polyline);
129                             }                           
130                         }
131                         //DisconnPolylineList.Add(polyline);
132                     }
133                     pFeature = pFeatCursor.NextFeature();
134                 }
135                 IEnumGeometry tEnumGeometry = (IEnumGeometry)Geometrybag;
136                 //IGeometry mergeGeomery = null;
137                 pTopOperatorFirst.ConstructUnion(tEnumGeometry);
138 
139                 pTopOperatorFirst.IsKnownSimple_2 = false;
140                 pTopOperatorFirst.Simplify();
141                 pFeatureFirst.Shape = pGeometryFirst;
142                 //pFeatureFirst.Store();
143                 IFeatureLayer featureLayer2 = map.get_Layer(1) as IFeatureLayer;
144                 IFeatureClass featureClass2 = featureLayer2.FeatureClass;
145                 AddPolyline(featureClass2, pGeometryFirst);
146             }
147             //workspaceEdit.StopEditOperation();
148             //workspaceEdit.StopEditing(true);           
149         }
150         private void AddPolyline(IFeatureClass pFeatureClass, IGeometry polyline)
151         {
152             IFeatureBuffer featureBuffer = pFeatureClass.CreateFeatureBuffer();
153             IFeatureCursor featureCursor;
154             featureCursor = pFeatureClass.Insert(true);
155             featureBuffer.Shape = polyline;
156             featureCursor.InsertFeature(featureBuffer);
157             featureCursor.Flush();
158             System.Runtime.InteropServices.Marshal.ReleaseComObject(featureCursor);
159         }
160         public List removeSameString(ArrayList stringArray)
161         {
162             //List用于存储从数组里取出来的不相同的元素
163             List distinctString = new List();
164             foreach (string eachString in stringArray)
165             {
166                 if (!distinctString.Contains(eachString))
167                     distinctString.Add(eachString);
168             }
169             return distinctString;
170         }
171 
172         protected override void OnUpdate()
173         {
174             Enabled = ArcMap.Application != null;
175         }
176     }
177 
178 }

X 问题及处置办法

X.1 HRESULT:0x80040215

在使用ITopologicalOperator求交集等操作的时候,有时会出现“ HRESULT:0x80040215”这个异常

原因是空间参考不一样所致。

将 SpatialReference 属性设为同一空间参考就不会出现 HRESULT:0x80040215 异常啦。

你可能感兴趣的:(基于C#的ArcEngine二次开发35:缓冲区分析)