||
本功能采用自定义菜单的方法,继承basecommand,具体步骤见教材。
0:新建项目GpBufferLayer,自定义生成一个菜单,命名为BufferSelectedLayerCmd.cs。在自定义菜单的代码中,修改onclick()事件的代码。
public override void OnClick() { if (null == m_hookHelper) return; if (m_hookHelper.FocusMap.LayerCount > 0) { BufferDlg bufferDlg = new BufferDlg(m_hookHelper); bufferDlg.Show(); } }
其中,BufferDlg是需要新建的一个窗体BufferDlg.cs,也就是缓冲区分析的界面。
1、新建 form 窗体。
添加 2 个 groupbox 控件,3 个 textbox 控件,2 个 combobox 控件,3 个button 控件,3 个 label 控件。
控件名称以及 text 属性需要修改,在下面的表里面。
Combobox 控件 cboUnits 的 Item 属性添加的内容为(可以自定义修改,此处为单位)
Unknown
Inches
Points
Feet
Yards
Miles
NauticalMiles
Millimeters
Centimeters
Decimeters
Meters
Kilometers
DecimalDegrees
2、窗体的代码如下:
(1)添加命名空间的引用
using System; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Geoprocessor; using ESRI.ArcGIS.Geoprocessing; using ESRI.ArcGIS.AnalysisTools;
(2)添加定义的变量
[DllImport("user32.dll")] private static extern int PostMessage(IntPtr wnd, uint Msg, IntPtr wParam, IntPtr lParam); private IMapControl4 MapControl; private IHookHelper m_hookHelper = null; private const uint WM_VSCROLL = 0x0115; private const uint SB_BOTTOM = 7;
(3)为窗口的入口函数添加参数,使缓冲区分析能够获得主窗口的参数(从主窗口传递变量进来,用的是hookHelper)。
public 缓冲区分析(IHookHelper hookHelper) { InitializeComponent(); m_hookHelper = hookHelper; MapControl = m_hookHelper as IMapControl4; }
(4)窗体的load事件中添加代码,使窗体得到当前地图中的图层列表,从而可以选择一个图层进行缓冲区分析。
private void 缓冲区分析_Load(object sender, EventArgs e) { if (null == m_hookHelper || null == m_hookHelper.Hook || 0 == m_hookHelper.FocusMap.LayerCount) return; //加载地图中所有要素到combo IEnumLayer layers = GetLayers(); layers.Reset(); ILayer layer = null; while ((layer = layers.Next()) != null) { cboLayers.Items.Add(layer.Name); } //默认选择第一个图层 if (cboLayers.Items.Count > 0) cboLayers.SelectedIndex = 0; string tempDir = System.IO.Path.GetTempPath(); txtOutputPath.Text = System.IO.Path.Combine(tempDir, ((string)cboLayers.SelectedItem + "_buffer.shp")); //设置默认的缓冲单位 int units = Convert.ToInt32(m_hookHelper.FocusMap.MapUnits); cboUnits.SelectedIndex = units; }
(5)在存放位置的按钮中弹出保存文件的窗口:
private void btnOutputLayer_Click(object sender, EventArgs e) { SaveFileDialog saveDlg = new SaveFileDialog(); saveDlg.CheckPathExists = true; saveDlg.Filter = "Shapefile (*.shp)|*.shp"; saveDlg.OverwritePrompt = true; saveDlg.Title = "Output Layer"; saveDlg.RestoreDirectory = true; saveDlg.FileName = (string)cboLayers.SelectedItem + "_buffer.shp"; DialogResult dr = saveDlg.ShowDialog(); if (dr == DialogResult.OK) txtOutputPath.Text = saveDlg.FileName; }
(6)添加缓冲区分析这个按钮的代码,也是这个功能的核心代码:
private void btnBuffer_Click(object sender, EventArgs e) { double bufferDistance; //将输入距离的字符型转换为double类型 double.TryParse(txtBufferDistance.Text, out bufferDistance); if (0.0 == bufferDistance) { MessageBox.Show("缓冲距离有错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } //判断输出路径是否合法 if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(txtOutputPath.Text)) || ".shp" != System.IO.Path.GetExtension(txtOutputPath.Text)) { MessageBox.Show("输出路径有问题!","提示",MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } //判断图层个数 if (m_hookHelper.FocusMap.LayerCount == 0) return; //从地图中获取图层 IFeatureLayer layer = GetFeatureLayer((string)cboLayers.SelectedItem); if (null == layer) { txtMessages.Text += "Layer " + (string)cboLayers.SelectedItem + "找不到!\r\n"; return; } //文本框拖到底部 ScrollToBottom(); //消息框中添加消息 txtMessages.Text += "缓冲图层: " + layer.Name + "\r\n"; txtMessages.Text += "\r\n正在获取地学处理器,请稍等...\r\n"; txtMessages.Text += DateTime.Now.ToString() + "\r\n"; txtMessages.Update(); //获得地学处理器的一个实例 Geoprocessor gp = new Geoprocessor(); gp.OverwriteOutput = true; txtMessages.Text += "开始进行缓冲区分析...\r\n"; txtMessages.Update(); //创建缓冲区工具的一个实例 ESRI.ArcGIS.AnalysisTools.Buffer buffer = new ESRI.ArcGIS.AnalysisTools.Buffer(layer, txtOutputPath.Text, Convert.ToString(bufferDistance) + " " + (string)cboUnits.SelectedItem); //执行缓冲区分析 IGeoProcessorResult results = (IGeoProcessorResult)gp.Execute(buffer, null); if (results.Status != esriJobStatus.esriJobSucceeded) { txtMessages.Text += "图层缓冲失败: " + layer.Name + "\r\n"; } txtMessages.Text += ReturnMessages(gp); //scroll the textbox to the bottom ScrollToBottom(); txtMessages.Text += "\r\n完成.\r\n"; txtMessages.Text += "-----------------------------------------------------------------------------------------\r\n"; //scroll the textbox to the bottom ScrollToBottom(); }
(7)添加(6)中需要调用的几个方法,添加取消按钮的代码:
private string ReturnMessages(Geoprocessor gp) { StringBuilder sb = new StringBuilder(); if (gp.MessageCount > 0) { for (int Count = 0; Count <= gp.MessageCount - 1; Count++) { System.Diagnostics.Trace.WriteLine(gp.GetMessage(Count)); sb.AppendFormat("{0}\n", gp.GetMessage(Count)); } } return sb.ToString(); } private IFeatureLayer GetFeatureLayer(string layerName) { //get the layers from the maps IEnumLayer layers = GetLayers(); layers.Reset(); ILayer layer = null; while ((layer = layers.Next()) != null) { if (layer.Name == layerName) return layer as IFeatureLayer; } return null; } private IEnumLayer GetLayers() { UID uid = new UIDClass(); uid.Value = "{40A9E885-5533-11d0-98BE-00805F7CED21}"; IEnumLayer layers = m_hookHelper.FocusMap.get_Layers(uid, true); return layers; } private void ScrollToBottom() { PostMessage((IntPtr)txtMessages.Handle, WM_VSCROLL, (IntPtr)SB_BOTTOM, (IntPtr)IntPtr.Zero); }
private void btnCancel_Click(object sender, EventArgs e) { this.Close(); }
3、调用缓冲区分析工具。
(1)生成,重新生成解决方案
(2)在debug中有一个dll。
(3)在需要使用这个工具的项目中添加引用,然后在命名空间的引用代码部分添加using GpBufferLayer;
别忘了还需要添加
using ESRI.ArcGIS.Geoprocessor;
using ESRI.ArcGIS.Geoprocessing;
(4)在toolbarcontrol中添加这个工具的调用方式:
axToolbarControl1.AddItem(new BufferSelectedLayerCmd(), -1, -1, false, 0, esriCommandStyles.esriCommandStyleIconAndText);
最终结果如图:
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-4-27 03:11
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社