1、ArcMap扩展开发实习指导书ArcMap拓展开发实习指导书1、以ArcGIS C#插件开发使用C#和ArcObject 10.1开发ArcGIS插件,开发的电脑上必须安装ArcGIS基础平台,同时必须安装支持.NET的开发库。在这里我们使用Visual Studio 2010作为开发环境。开发步骤如下:1、启动Visual Studio 2010,创建Visual C# 的类库项目,名称为BufferExSolution,如图2_1所示。2_1 创建项目2、在解决方案资源管理器中,选择BufferExSolution项目,右键添加新建项目,选在ArcGIS模板下的Base Command模板
2、,将名称设置为BufferEx,如图2_2所示,点击“添加”按钮,出现如图2_3所示的选择项,选择第二项,其意义为在ArcMap、MapControl或者PageLayoutControl中都可以使用新建的插件。2_23、添加名为“BufferDlg”的Windows窗体,如图2_4所示。这样在资源管理器中就出现了图2_44、为BufferDlg窗体添加控件,控件布局如图2_5所示。控件属性如表2_1所示。图2_5表2_1控件类型Name属性Text属性其它属性LabellblChoseLayer选择图层LabellblRadio缓冲区半径LabellblOutPath输出路径Comboxcb
3、oLayersTextBoxtxtBufferDistanceText=0.1ComboxcboUnitsItems= UnknownInchesPointsFeetYardsMilesNauticalMilesMillimetersCentimetersMetersKilometersDecimalDegreesDecimetersTextBoxtxtOutputPathEnable=falseButtonbtnOutputLayerButtonbtnBuffer输出GroupBoxgpbTips提示TextBoxtxtMessagesMultiLineButtonbtnCancel关闭5、
4、为修改BufferCmd类,首先修改其构造函数:public BufferCmd() base.m_category = 缓冲区创建工具; base.m_caption = 缓冲区创建; base.m_message = This should work in ArcMap/MapControl/PageLayoutControl; base.m_toolTip = 缓冲区创建; base.m_name = BufferCmd; try string bitmapResourceName = GetType().Name + .bmp; base.m_bitmap = new Bitmap(G
5、etType(), bitmapResourceName); catch (Exception ex) System.Diagnostics.Trace.WriteLine(ex.Message, Invalid Bitmap); 6、为OnClick函数添加如下代码:public override void OnClick() if (null = m_hookHelper) return;if (m_hookHelper.FocusMap.LayerCount 0) BufferDlg bufferDlg = new BufferDlg(m_hookHelper); bufferDlg.S
6、how(); 其中, IHookHelper m_hookHelper主要在用在自定义类型于AO/AE带的的ICommand或ITool等。在BufferCmd类中,OnCreate函数将object类型的参数hook传递给m_hookHelper,而m_hookHelper又可以作为参数在OnClick函数中传递给BufferDlg类,这样就实现了ArcMap中数据向插件传递,从而实现插件对宿主程序中数据的操作、拓展了宿主程序的功能。OnCreate函数的代码如下:public override void OnCreate(object hook) if (hook = null) retu
7、rn;try m_hookHelper = new HookHelperClass(); m_hookHelper.Hook = hook; if (m_hookHelper.ActiveView = null) m_hookHelper = null; catch m_hookHelper = null; if (m_hookHelper = null) base.m_enabled = false; else base.m_enabled = true;OnClick函数的作用就是:当ArcMap中加载了该插件,只要点击该插件的按钮,则就执行OnClick函数,也就是将BufferDlg窗
8、体调出来。下面,我们将为BufferDlg窗体添加控件响应事件。7、修改BufferDlg类的构造函数,使构造函数有一个类型为IHookHelper的参数,实现从BufferCmd类中接收宿主程序的数据。public BufferDlg(IHookHelper hookHelper) InitializeComponent(); m_hookHelper = hookHelper; 通过IHookHelper类型的实例将宿主程序的对象传到插件中的机制如下:IHookHelper m_hookHelper = new HookHelperClass();m_hookHelper.Hook = t
9、his.axMapControl1.Object ;这样就可以把AxMapControl传递给其它要用到的地方,再通过IHookHelper.ActiveView和IHookHelper.FocusMap属性来获取IActiveView和IMap对象,通过这两个接口进行更一步的操作。8、完善BufferDlg类,为其添加相应的字段,同时依次为表2_1中列出的控件添加相应的事件响应,BufferDlg类实现代码如下:public partial class BufferDlg : Form /委托机制,目的是在.Net环境中使用Win32函数 DllImport(user32.dll) priv
10、ate static extern int PostMessage(IntPtr wnd, uint Msg, IntPtr wParam, IntPtr lParam);private IHookHelper m_hookHelper = null; private const uint WM_VSCROLL = 0x0115; private const uint SB_BOTTOM = 7; public BufferDlg(IHookHelper hookHelper) InitializeComponent(); m_hookHelper = hookHelper; private
11、void bufferDlg_Load(object sender, EventArgs e) if (null = m_hookHelper | null = m_hookHelper.Hook | 0 = m_hookHelper.FocusMap.LayerCount) return;/将ArcMap中的图层名称显示到combox中 IEnumLayer layers = GetLayers(); layers.Reset(); ILayer layer = null; while (layer = layers.Next() != null) cboLayers.Items.Add(l
12、ayer.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); c
13、boUnits.SelectedIndex = units; private void btnOutputLayer_Click(object sender, EventArgs e) /设置输出shp文件路径 SaveFileDialog saveDlg = new SaveFileDialog(); saveDlg.CheckPathExists = true; saveDlg.Filter = Shapefile (*.shp)|*.shp; saveDlg.OverwritePrompt = true; saveDlg.Title = 输出图层; saveDlg.RestoreDire
14、ctory = true; saveDlg.FileName = (string)cboLayers.SelectedItem + _buffer.shp; DialogResult dr = saveDlg.ShowDialog(); if (dr = DialogResult.OK) txtOutputPath.Text = saveDlg.FileName; private void btnBuffer_Click(object sender, EventArgs e) double bufferDistance; /获取缓冲区半径 double.TryParse(txtBufferDi
15、stance.Text, out bufferDistance); if (0.0 = bufferDistance) MessageBox.Show(缓冲区半径不合法!); return; /检查输出路径合法性 if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(txtOutputPath.Text) | .shp != System.IO.Path.GetExtension(txtOutputPath.Text) MessageBox.Show(输出文件名不正确!); return; /检测宿主程序(ArcMap)
16、中是否存在图层 if (m_hookHelper.FocusMap.LayerCount = 0) return; /从ArcMap中获得图层 IFeatureLayer layer = GetFeatureLayer(string)cboLayers.SelectedItem); if (null = layer) txtMessages.Text += Layer + (string)cboLayers.SelectedItem + 不能被找到!rn; return; /设置消息框有滚动条 ScrollToBottom(); txtMessages.Text += rn分析开始,这可能需要
17、几分钟时间,请稍候.rn; txtMessages.Update(); /获得geoprocessor实例 Geoprocessor gp = new Geoprocessor(); gp.OverwriteOutput = true; /创建缓冲区生成工具 ESRI.ArcGIS.AnalysisTools.Buffer buffer = new ESRI.ArcGIS.AnalysisTools.Buffer(layer, txtOutputPath.Text, Convert.ToString(bufferDistance) + + (string)cboUnits.SelectedIt
18、em); buffer.dissolve_option = ALL;/这个要设成ALL,否则相交部分不会融合 /buffer.line_side = FULL;/默认是FULL,最好不要改否则出错 /buffer.line_end_type = ROUND;/默认是ROUND,最好不要改否则出错/执行缓冲区生成工具 IGeoProcessorResult results = null; try results = (IGeoProcessorResult)gp.Execute(buffer, null); catch (Exception ex) txtMessages.Text += Fai
19、led to buffer layer: + layer.Name + rn; if (results != null &results.Status != esriJobStatus.esriJobSucceeded) txtMessages.Text += Failed to buffer layer: + layer.Name + rn; ScrollToBottom();txtMessages.Text += rn分析完成.rn; txtMessages.Text += -rn; ScrollToBottom(); private string ReturnMessages(Geopr
20、ocessor 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(0n, gp.GetMessage(Count); return sb.ToString(); / / 根据名称获取图层对象 / / / private IFeatureLayer GetF
21、eatureLayer(string layerName) /从ArcMap中获得layers 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 = 40A
22、9E885-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.C
23、lose(); 9、编译运行程序,提示缺少引用。按照提示添加相应的引用。重新编译运行,则程序生成一个名为BufferExSolution.dll和一个名为BufferExSolution.tlb的文件。这两个程序就是插件程序,在ArcMap中可以直接使用。在ArcMap中使用上面生成的插件的步骤如下:1、启动ArcMap程序,通过“Tools”/“Customize”菜单打开Customize对话框,如图2_6所示。图2_62、在Toolbars页面点击“New”按钮,新建一个名为Buffer_Create的工具按钮,如图2_7所示。图2_73、在Commands页面点击“Add from file”按钮,选择创建的插件文件,如图2_8所示。图2_8点击“打开”,则插件就被安装到了宿主程序,也即ArcMap程序中。如图2_9所示。图2_94、将如图2_9所示的“缓冲区分析”拖拽到第二部所创建的工具按钮上,关闭Customize对话框,调整Buffer_Create工具按钮的位置。至此,该插件就可以使用了。图2_10是插件运行实例。图2_10上面这个例子仅仅只是给读者演示了C#开发GIS插件的可行性例子,给读者一个思路。C#是语言,要想很好的开发ArcGIS插件,必须认真学习ArcObject/ArcEngine,建议读者阅读相关书籍。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1