首先小伙伴们,可以参考arcgis开发学习视频。
https://edu.csdn.net/course/detail/25535
最近有小伙伴,有这样的需求,在三调项目制作数据中遇到这样的问题。现在有一份很多的图斑shapefile数据,和一份行政村的shapefile数据。现在要做的工作是,将图斑中的数据每个图斑与行政村叠加,然后将与之相交的行政村的名字字段写到图斑的行政村字段中,如果有多个行政村,其中相交的面积超过一定的值,那么必须将该行政村作为有效值填入到图斑中。
一开始,我想使用python来实现,但想想使用arcpy在arcgis中拓扑分析比较弱,最后使用了c#来开发了这个工具。这里使用的arcgis addin的方式来开发这个工具。设计的思路是,利用图斑图层遍历所有的面,将每个面与图层行政村相交,然后计算出与图斑相交的每一个行政村的相交面积,如果面积大于一定的阈值,那么就取出该行政村的名称字段值填入到图斑的对应字段。
下面来看一下arcgis关于addin方面的开发。首先我使用的是visual studio2012和arcgis object10.2开发,关于安装visual studio和arcgis object大家可以参考相关的网络资料。下面来看一下具体的步骤。
来看一下,整个工程结构如下图所示。
这里要重写Button1里面的Onclick方法,这样才能与之对应响dockwindow
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinDockUpdateProperty
{
public class Button1 : ESRI.ArcGIS.Desktop.AddIns.Button
{
public Button1() {
}
protected override void OnClick()
{
IDockableWindowManager dockWindowManager = ArcMap.DockableWindowManager as IDockableWindowManager;
if (dockWindowManager != null)
{
UID windowID = new UIDClass();
windowID.Value = ThisAddIn.IDs.DockableWindow;
IDockableWindow docWin = dockWindowManager.GetDockableWindow(windowID);
if (docWin.IsVisible())
{
docWin.Show(false);
}
else
{
docWin.Show(true);
}
}
ArcMap.Application.CurrentTool = null;
}
protected override void OnUpdate()
{
Enabled = ArcMap.Application != null;
}
}
}
下面来编写一下与本次操作有关的代码。基本上就是Arcengiene的二次开发,实现的思路和前面说过的一样。具体可以参考代码的实现。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using System.Collections.ObjectModel;
namespace WinDockUpdateProperty
{
///
/// Designer class of the dockable window add-in. It contains user interfaces that
/// make up the dockable window.
///
public partial class DockableWindow : UserControl
{
public static IFeatureLayer featureLayerTB = null;
public static IFeatureLayer featureLayerJX = null;
private IMap m_map;
IActiveView pAv;
ObservableCollection features;
public static IFeatureLayer featureLayer = null;
public DockableWindow(object hook)
{
InitializeComponent();
this.Hook = hook;
initUI();
}
public void initUI() {
m_map = ArcMap.Document.FocusMap;
pAv = m_map as IActiveView;
/*或者下面这种写法*/
//pAv = ArcMap.Document.ActivatedView;
IFeatureLayer featureLayer;
features = new ObservableCollection();
for (int i = 0; i < m_map.LayerCount; i++)
{
if (m_map.get_Layer(i) is IFeatureSelection)
{
featureLayer = m_map.get_Layer(i) as IFeatureLayer;
if (featureLayer == null)
break;
features.Add(new FeatureInfos(featureLayer.Name, featureLayer, Convert.ToString(i)));
}
}
CB_JXLayer.DataSource = features;
CB_TBLayer.DataSource = features;
CB_JXLayer.ValueMember = "con";
CB_JXLayer.DisplayMember = "title";
CB_JXLayer.SelectedValue = "con";
CB_TBLayer.ValueMember = "con";
CB_TBLayer.DisplayMember = "title";
CB_TBLayer.SelectedValue = "con";
}
///
/// Host object of the dockable window
///
private object Hook
{
get;
set;
}
///
/// Implementation class of the dockable window add-in. It is responsible for
/// creating and disposing the user interface class of the dockable window.
///
public class AddinImpl : ESRI.ArcGIS.Desktop.AddIns.DockableWindow
{
private DockableWindow m_windowUI;
public AddinImpl()
{
}
protected override IntPtr OnCreateChild()
{
m_windowUI = new DockableWindow(this.Hook);
return m_windowUI.Handle;
}
protected override void Dispose(bool disposing)
{
if (m_windowUI != null)
m_windowUI.Dispose(disposing);
base.Dispose(disposing);
}
}
/*处理按钮*/
private void BTN_Deal_Click(object sender, EventArgs e)
{
double splitArea = 50;
splitArea =Convert.ToDouble( this.TB_YZ.ToString());
/*遍历出每一条记录*/
IFeatureCursor pFeatureCur = featureLayerTB.Search(null, false);
IFeature pFeature = pFeatureCur.NextFeature();
int m = 1;
while (pFeature != null)
{
m++;
ISpatialFilter spatialFilter = new SpatialFilter();
spatialFilter.Geometry = pFeature.Shape;
spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
/*每一条记录与界线求交*/
IFeatureCursor featureCursor = featureLayerJX.Search(spatialFilter, false);
IFeature tmpFeature = featureCursor.NextFeature();
string strXZCMC = "";
int index = 0;
Console.WriteLine("正在处理第" + m + "条数据\r\n");
try
{
while (tmpFeature != null)
{
if (tmpFeature.Shape.GeometryType == esriGeometryType.esriGeometryPolygon && pFeature.Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
{
IGeometry pIntersectGeo = new PolygonClass();
IGeometry pSecondPolygon = new PolygonClass();
IGeometry pFirstPolygon = new PolygonClass();
IGeometry pFirstGeometry = pFeature.Shape;
IGeometry pSecondGeometry = tmpFeature.Shape;
ITopologicalOperator pFirstTopoOperator = (pFeature.Shape) as ITopologicalOperator;
ITopologicalOperator pSecondTopoOperator = pSecondPolygon as ITopologicalOperator;
pSecondPolygon = pSecondTopoOperator.Union(pSecondGeometry) as IPolygon;
IGeometry outGeometry = pFirstTopoOperator.Intersect(pSecondGeometry, esriGeometryDimension.esriGeometry2Dimension);
IGeometry tmpGeometry = outGeometry;
IArea pArea = tmpGeometry as IArea;
double dArea = pArea.Area;
if (dArea < splitArea)
{
tmpFeature = featureCursor.NextFeature();
continue;
}
else
{
String tmpXZCMC = tmpFeature.get_Value(tmpFeature.Fields.FindField("XZQMC_X")).ToString();
/*第一条记录,不用逗号分隔*/
if (index == 0)
{
strXZCMC += tmpXZCMC;
index++;
tmpFeature = featureCursor.NextFeature();
}
/*多于一条记录,用逗号分隔*/
else if (index > 0)
{
strXZCMC += "," + tmpXZCMC;
index++;
tmpFeature = featureCursor.NextFeature();
}
}
}
}
pFeature.set_Value(pFeature.Fields.FindField("XZCMC"), strXZCMC);
pFeature.Store();
pFeature = pFeatureCur.NextFeature();
strXZCMC = "";
index = 0;
}
catch (Exception ex)
{
MessageBox.Show("出现了错误:" + ex.ToString());
}
}
}
}
}
编写好程序后,现在我就是将编写好的addin放到arcgis里面去调试了,选择【Customize】
然后选择【Customize Mode】,弹出如下框。依次选择【Commands】、【Add From File..】
如下图所示,将开发的批量修改属性拖拽到arcgis的工具栏。
最后添加arcgis里面的图层。如下图所示,然后运行,最后结果如下图所示。
更多内容,请关注公众号