ArcEngine|使用GP工具实现缓冲区分析与叠置分析
所有的代码已经传到了我的GitHub,需要的请自取,GitHub项目地址:https://github.com/Weltra/T_ArcMap
GP工具简介
地理处理是ArcGIS 的一个重要概念,其目的是便于用户自动执行GIS的空间分析和建模任务。地理处理工具是将GIS中常用、可重复的操作,如提取与叠加数据、更改地图投影等封装成一个具有参数输人输出的交互式图形界面。地理处理通过脚本将一系列的工具按照一定的操作顺序结合在一起,共同完成一项地理处理任务。其工具都储存在工具箱中,ArcGIS提供了数百种工具,并根据功能将它们分别放到了十余个工具箱中。ArcToolbox是所有工具的集合, 提供工具运行的环境。在ArcGIS Engine编程过程中,可以通过调用GP工具来实现某些常用的功能。
调用GP工具主要应用了Geoprocessor类,这个类也可以调用人们自定义的工具。在使用Geoprocessor 类时,需要首先定义一个Geoprocessor 对象, Geoprocessor是简化调用Geoprocessing工具任务的主要对象。这个对象是执行ArcGIS 中任何Geoprocessing 工具的唯一访问点,它是一个粗粒度对象, 包含了许多属性和方法,在设置完相关的参数后,则通过Geoprocessor 的Excute函数来执行,Excute方法中需要一个操作对象作为参数,如lntersect、Clip 等,具体包含哪些操作类,可通过ArcToolBox和Esri的帮助文档查找。
缓冲区分析
(1)建立【缓冲区分析】窗体
该窗体用于显示及设置输入图层、缓冲半径、融合类型、输出路径以及执行缓冲区分析功能的按钮等,其界面入下图所示:
(2)功能实现的核心代码
public partial class BufferAnalysisTool : Form
{
public IMap pMap { get; set; }
public AxMapControl mapControl { get; set; }
public BufferAnalysisTool()
{
InitializeComponent();
}
private void BufferAnalysisTool_Load(object sender, EventArgs e)
{
pMap = mapControl.Map;
//向图层comboBox1中预置噪音来源
if (pMap.LayerCount > 0)
{
for (int i = 0; i < pMap.LayerCount; i++)
{
ILayer pLayer = pMap.get_Layer(i);
if (pLayer != null)
{
if (pLayer is IFeatureLayer)
{
comboBox_InputDataset.Items.Add(pLayer.Name);
}
}
}
comboBox_InputDataset.SelectedIndex = 0;
DistanceTextBox.Text = "500";
this.comboBox1.Items.Add("NONE");//选择项1
this.comboBox1.Items.Add("ALL");
comboBox1.SelectedIndex = 0;
textEdit_Output.Text = System.Environment.CurrentDirectory + "buffer.shp";
}
else return;
}
private void button3_Click(object sender, EventArgs e)
{
this.Close();
}
private void button1_Click(object sender, EventArgs e)
{
SaveFileDialog flg = new SaveFileDialog();
flg.Title = "保存路径";
flg.Filter = "ShpFile(*shp)|*.shp";
flg.ShowDialog();
textEdit_Output.Text = flg.FileName;
}
private ILayer GetLayerByName(IMap pMap, string layerName)
{
ILayer pLayer = null;
ILayer tempLayer = null;
try
{
for (int i = 0; i < pMap.LayerCount; i++)
{
tempLayer = pMap.Layer[i];
if (tempLayer.Name.ToUpper() == layerName.ToUpper()) //判断名字大写是否一致
{
pLayer = tempLayer;
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return pLayer;
}
private void button2_Click(object sender, EventArgs e)
{
try
{
ILayer inputDataset = GetLayerByName(pMap, comboBox_InputDataset.Text.Trim());
IFeatureLayer inputLayer = inputDataset as IFeatureLayer;
//缓冲区分析-GP工具调用
Geoprocessor gp = new Geoprocessor();
gp.OverwriteOutput = true;
ESRI.ArcGIS.AnalysisTools.Buffer pBuffer = new ESRI.ArcGIS.AnalysisTools.Buffer();
pBuffer.in_features = inputLayer;
//设置生成结果存储路径
pBuffer.out_feature_class = textEdit_Output.Text;
//设置缓冲区距离
string buffer_distance = DistanceTextBox.Text + " Meters";
pBuffer.buffer_distance_or_field = buffer_distance;
pBuffer.dissolve_option = comboBox1.Text;
//执行缓冲区分析
gp.Execute(pBuffer, null);
//将生成结果添加到地图中
string pPath = System.IO.Path.GetDirectoryName(textEdit_Output.Text); //获取文件路径
string pName = System.IO.Path.GetFileName(textEdit_Output.Text); //获取文件名
this.mapControl.AddShapeFile(pPath, pName);
this.mapControl.MoveLayerTo(1, 0);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
(3)在 menuStrip 中添加一个geoProcessing选项,并在其子选项中BufferTool选项,为其绑定 Click 事件。在 Click 事件处理方法中添加代码,显示【裁剪】窗体。
private void bufferToolToolStripMenuItem_Click(object sender, EventArgs e)
{
GeoProcessing.BufferAnalysisTool BF = new GeoProcessing.BufferAnalysisTool();
BF.mapControl = this.axMapControl1;
BF.ShowDialog();
}
叠置分析
(1)建立叠置分析窗体
该窗体用于显示及设置与参与裁剪的数据、裁剪后输出的数据路径以及执行裁剪功能的按钮等,其界面入下图所示:
(2)在叠置分析窗体中完成裁剪功能的代码如下:
public partial class OverlayAnalysisTool : Form
{
public OverlayAnalysisTool()
{
InitializeComponent();
}
//定义全局变量
public IMap pMap { get; set; }
public AxMapControl mapControl { get; set; }
private void OverlayAnalysisTool_Load(object sender, EventArgs e)
{
try
{
pMap = mapControl.Map;
if (pMap == null)
return;
//清空combobox
comboBox_InputDataset.Items.Clear();
comboBox_ClipDataset.Items.Clear();
string layerName; //用于储存图层名字
for (int i = 0; i < pMap.LayerCount; i++)
{
layerName = pMap.Layer[i].Name;
comboBox_InputDataset.Items.Add(layerName);
comboBox_ClipDataset.Items.Add(layerName);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void button2_OK_Click(object sender, EventArgs e)
{
if (pMap == null)
return;
//获取数据集
ILayer inputDataset = GetLayerByName(pMap, comboBox_InputDataset.Text.Trim());
ILayer clipDataset = GetLayerByName(pMap, comboBox_ClipDataset.Text.Trim());
if (inputDataset != null && clipDataset != null)
{
IFeatureLayer inputLayer = inputDataset as IFeatureLayer;
IFeatureLayer clipLayer = clipDataset as IFeatureLayer;
//利用裁剪方法来进行叠加分析
IBasicGeoprocessor bGP = new BasicGeoprocessorClass();
bGP.SpatialReference = pMap.SpatialReference; //设置空间参考
//创建FeatureClassNameClass对象,用于获取输入数据集的一些基本信息
IFeatureClassName pOutput = new FeatureClassName() as IFeatureClassName;
pOutput.FeatureType = inputLayer.FeatureClass.FeatureType;
pOutput.ShapeFieldName = inputLayer.FeatureClass.ShapeFieldName;
pOutput.ShapeType = inputLayer.FeatureClass.ShapeType;
//利用IDataset获得IWorkspaceName
string fileDirectory = System.IO.Path.GetDirectoryName(textEdit_Output.Text.Trim());
string fileName = System.IO.Path.GetFileName(textEdit_Output.Text.Trim());
IWorkspaceFactory pWsFc = new ShapefileWorkspaceFactory();
IWorkspace pWs = pWsFc.OpenFromFile(fileDirectory, 0); //创建一个工作空间对象
IDataset pDataset = pWs as IDataset;
IWorkspaceName pWsN = pDataset.FullName as IWorkspaceName; //获取工作空间的信息(获取输出路径)
IDatasetName pDatasetName = pOutput as IDatasetName; //获取或设置数据集中成员的名称信息
pDatasetName.Name = fileName; //设置数据集中的数据成员的名字
pDatasetName.WorkspaceName = pWsN; //设置输出的工作空间(输出路径)
IFeatureClass featureClass = bGP.Clip(inputLayer.FeatureClass as ITable, false, clipLayer.FeatureClass as ITable, false, 0.01, pOutput);
if (featureClass != null)
{
IFeatureLayer featLayer = new FeatureLayerClass();
featLayer.FeatureClass = featureClass;
featLayer.Name = featureClass.AliasName;
//将结果添加到控件中
mapControl.AddLayer(featLayer);
mapControl.Refresh();
}
}
}
private void simpleButton_Cancel_Click(object sender, EventArgs e)
{
this.Close();
}
private ILayer GetLayerByName(IMap pMap, string layerName)
{
ILayer pLayer = null;
ILayer tempLayer = null;
try
{
for (int i = 0; i < pMap.LayerCount; i++)
{
tempLayer = pMap.Layer[i];
if (tempLayer.Name.ToUpper() == layerName.ToUpper()) //判断名字大写是否一致
{
pLayer = tempLayer;
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return pLayer;
}
private void simpleButton_Output_Click(object sender, EventArgs e)
{
SaveFileDialog flg = new SaveFileDialog();
flg.Title = "保存路径";
flg.Filter = "ShpFile(*shp)|*.shp";
flg.ShowDialog();
textEdit_Output.Text = flg.FileName;
}
}
(3)在主窗体调用叠置分析窗口
在 menuStrip 中添加一个geoProcessing选项,并在其子选项中添加overlapTool选项,为其绑定 Click 事件。在 Click 事件处理方法中添加代码,显示【裁剪】窗体。
private void overlapToolToolStripMenuItem_Click(object sender, EventArgs e)
{
GeoProcessing.OverlayAnalysisTool oA = new GeoProcessing.OverlayAnalysisTool();
oA.mapControl = this.axMapControl1;
oA.ShowDialog();
}
结果
缓冲区分析功能
导入数据
打开缓冲区分析工具
设置参数
选择输出路径
缓冲区分析结果
叠置分析-裁剪功能
导入数据
打开叠置分析工具
设置参数
选择输出路径
叠置分析结果