ArcGIS Add-in插件开发从0到1及实际案例分享

同学做毕设,要求我帮着写个ArcGIS插件,实现功能为:遍历所有图斑,提取相邻图斑的公共边长及其他属性(包括相邻图斑的ID),链接到属性表中。搞定后在这里做个记录。本文分两大部分:

  • ArcGIS插件开发流程
  • 实际案例分享

一、ArcGIS插件开发流程

该部分不涉及具体业务,力求以最快速度了解ArcGIS Add-in插件从开发到使用的具体流程。

1.新建项目

 

2.编写业务代码

3.编译

4.安装插件

    

5.使用插件

二、实际案例分享

上面已经说了,案例来源于实际的需求,此处想必没有比直接上代码更实用更有feel了。实现功能为:遍历所有图斑,提取相邻图斑的公共边长及其他属性(包括相邻图斑的ID),并保存到文本文件中。注释已经写的很详细了,所以具体过程也不多说,有啥问题直接留言,我会看到的~

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Text;
  4 using System.IO;
  5 using ESRI.ArcGIS.Framework;
  6 using ESRI.ArcGIS.Carto;
  7 using ESRI.ArcGIS.ArcMapUI;
  8 using System.Windows.Forms;
  9 using ESRI.ArcGIS.Geometry;
 10 using ESRI.ArcGIS.Geodatabase;
 11 using System.Runtime.InteropServices;
 12 using ESRI.ArcGIS.ADF.CATIDs;
 13 
 14 namespace SharedSide
 15 {
 16     public class SharedSide : ESRI.ArcGIS.Desktop.AddIns.Button
 17     {
 18         private IApplication m_application;
 19         private static IMap map;
 20 
 21         public SharedSide()
 22         {
 23 
 24         }
 25 
 26         protected override void OnClick()
 27         {
 28             m_application = ArcMap.Application;
 29             map = (m_application.Document as IMxDocument).FocusMap;
 30 
 31             FormSelect formSelect = new FormSelect();
 32             IEnumLayer layers = map.get_Layers(null, false);
 33             layers.Reset();
 34             ILayer layer = layers.Next();
 35             while (layer != null)
 36             {
 37                 formSelect.cmbLayers.Items.Add(layer.Name);
 38                 layer = layers.Next();
 39             }
 40             formSelect.ShowDialog();
 41 
 42             if (formSelect.IsOK)
 43             {
 44                 ILayer selectedLayer = GetLayerByName(formSelect.cmbLayers.Text);
 45                 IFeatureLayer pFeatureLayer = selectedLayer as IFeatureLayer;
 46                 int featureCount = pFeatureLayer.FeatureClass.FeatureCount(null);
 47                 IFeatureCursor featureCursor = pFeatureLayer.Search(null, false);
 48                 IFeature pFeature = null;
 49 
 50                 // 最大相邻图斑数
 51                 int maxNumAdajacency = 0;
 52                 // 具有相邻图斑的要素
 53                 List<IFeature> featuresHasAdjacency = new List<IFeature>();
 54                 // 对应featureHasAdjacency的相邻图斑
 55                 List<List<IFeature>> adjacentFeatures = new List<List<IFeature>>();
 56                 // 对应adjacentFeatures的公共边长度
 57                 List<List<double>> adjacentLengths = new List<List<double>>();
 58 
 59                 // 提取边相邻的相邻图斑并计算公共边长度
 60                 while ((pFeature = featureCursor.NextFeature()) != null)
 61                 {
 62                     // 与pFeature相邻的图斑
 63                     List<IFeature> adjacentFeature = AdjacentPolygons(pFeature, pFeatureLayer);
 64                     // pFeature与adjacentFeature的公共边长度
 65                     List<double> adjacentLength = new List<double>();
 66 
 67                     // 计算公共边长度并去掉只有公共点相邻的图斑
 68                     if (adjacentFeature.Count > 0)
 69                     { 
 70                         for (int i = 0; i < adjacentFeature.Count; i++)
 71                         {
 72                             double length = LengthOfSide((pFeature.Shape as IPolygon), (adjacentFeature[i].Shape as IPolygon));
 73                             if (length == 0)
 74                             {// 如果只有公共点相邻,则移除
 75                                 adjacentFeature.Remove(adjacentFeature[i]);
 76                             } 
 77                         }
 78 
 79                         for (int i = 0; i < adjacentFeature.Count; i++)
 80                         {
 81                             double length = LengthOfSide((pFeature.Shape as IPolygon), (adjacentFeature[i].Shape as IPolygon));
 82                             adjacentLength.Add(length);
 83                         }
 84                     }
 85 
 86                     if (adjacentFeature.Count > 0)
 87                     {// 如果去掉只有公共点相邻的情况pFeature仍有图斑与之相邻
 88                         featuresHasAdjacency.Add(pFeature);
 89                         adjacentFeatures.Add(adjacentFeature);
 90                         adjacentLengths.Add(adjacentLength);
 91                     }
 92 
 93                     // 3.查找最多相邻图斑数
 94                     if (adjacentFeature.Count > maxNumAdajacency)
 95                     {
 96                         maxNumAdajacency = adjacentFeature.Count;
 97                     }
 98                 }
 99                 System.Runtime.InteropServices.Marshal.ReleaseComObject(featureCursor);
100 
101                 // 将相邻图斑的公共边长度及DLBM属性写入文本文件保存
102                 string text = "OBJECTID";
103                 for (int i = 0; i < maxNumAdajacency; i++)
104                 {
105                     string str = (",相邻" + (i + 1) + "-OBJECTID") + (",相邻" + (i + 1) + "-公共边长") + (",相邻" + (i + 1) + "-DLBM");
106                     text += str;
107                 }
108 
109                 WriteData(formSelect.txtPath.Text, text);
110 
111                 int n = featuresHasAdjacency.Count;
112                 for (int i = 0; i < n; i++)
113                 {
114                     int nIndex = featuresHasAdjacency[i].Table.FindField("OBJECTID");
115                     string str = featuresHasAdjacency[i].get_Value(nIndex).ToString();
116                     int m = adjacentFeatures[i].Count;
117                     for (int j = 0; j < m; j++)
118                     {
119                         str += "," + adjacentFeatures[i][j].get_Value(adjacentFeatures[i][j].Table.FindField("OBJECTID")).ToString();
120                         str += "," + adjacentLengths[i][j].ToString();
121                         str += "," + adjacentFeatures[i][j].get_Value(adjacentFeatures[i][j].Table.FindField("DLBM")).ToString();
122                     }
123                     WriteData(formSelect.txtPath.Text, str);
124                 }
125                 MessageBox.Show("计算完成!");
126             }
127         }
128 
129         protected override void OnUpdate()
130         {
131             Enabled = ArcMap.Application != null;
132         }
133 
134         // 通过图层名称查找指定图层
135         public static ILayer GetLayerByName(string lyrName)
136         {
137             ILayer findLayer = null;
138             IEnumLayer pEnumLayer = map.get_Layers();
139             pEnumLayer.Reset();
140             ILayer pLayer = pEnumLayer.Next();
141             while (pLayer != null)
142             {
143                 if (pLayer.Name == lyrName)
144                 {
145                     findLayer = pLayer;
146                 }
147                 pLayer = pEnumLayer.Next();
148             }
149             return findLayer;
150         }
151 
152         // 判断线是否为面的边界
153         public static bool isBoundary(IPolyline iPolyline, IPolygon iPolygon)
154         {
155             bool isBoundary;
156             ITopologicalOperator topoOper = iPolygon as ITopologicalOperator;
157             IPolyline boundLine = topoOper.Boundary as IPolyline;
158             IRelationalOperator reltOper = iPolyline as IRelationalOperator;
159             isBoundary = reltOper.Overlaps(boundLine);
160             return isBoundary;
161         }
162 
163         // 查找当前图层中与某图斑相邻的其他图斑(包括有公共边的和公共点的)
164         public static List<IFeature> AdjacentPolygons(IFeature iFeature, IFeatureLayer featureLayer)
165         {
166             List<IFeature> listFeature = new List<IFeature>();
167             IRelationalOperator reltOperator = iFeature.Shape as IRelationalOperator;
168             int featureCount = featureLayer.FeatureClass.FeatureCount(null);
169             IFeatureCursor featureCursor = featureLayer.Search(null, false);
170             IFeature feature = null;
171             while ((feature = featureCursor.NextFeature()) != null)
172             {
173                 if (feature.OID == iFeature.OID)
174                 {
175                     continue;
176                 }
177                 bool isAdjacent = reltOperator.Touches(feature.Shape);
178                 if (isAdjacent)
179                 {
180                     listFeature.Add(feature);
181                 }
182             }
183             return listFeature;
184         }
185 
186         // 计算两个图斑公共边的长度
187         public static double LengthOfSide(IPolygon iPolygon1, IPolygon iPolygon2)
188         {
189             IPolyline polyline;
190             ITopologicalOperator topoOper = iPolygon1 as ITopologicalOperator;
191             polyline = topoOper.Intersect(iPolygon2, esriGeometryDimension.esriGeometry1Dimension) as IPolyline;
192             return polyline.Length;
193         }
194 
195         // 写入数据到文件
196         private static void WriteData(string filePath, string text)
197         {
198             FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write);
199             StreamWriter sw = new StreamWriter(fs);
200             sw.WriteLine(text);
201             sw.Close();
202             fs.Close();
203         }
204     }
205 }
原文地址:https://www.cnblogs.com/yif1991/p/5238233.html