arcgisengine二次开发——提高篇.doc_第1页
arcgisengine二次开发——提高篇.doc_第2页
arcgisengine二次开发——提高篇.doc_第3页
arcgisengine二次开发——提高篇.doc_第4页
arcgisengine二次开发——提高篇.doc_第5页
已阅读5页,还剩73页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

arcgis engine二次开发提高篇1 缩略图(鹰眼)鹰眼功能是gis的主要功能之一,当地图范围很大时,它可以很好的为用户指明当前地图的范围。在本小节中我们将学习如何制作这种鹰眼。1.1 添加控件新建一个c#.net项目,项目名称为overview,将form1的名字设置为mainform,并添加toolbarcontrol 、两个mapcontrol和licencecontrol等四个控件。布局如下图所示。左边的axmapcontrol1用于地图数据显示和操作,右边axmapcontrol2用于鹰眼显示。图 1 界面布局在toolbarcontrol 加载添加数据按钮和地图浏览的功能按钮,如下图所示,并将toolbarcontrol的伙伴控件设为axmapcontrol1。图 2添加按钮1.2 代码添加及解释鹰眼用来显示主窗体当前视图范围在全景视图中的位置,在arcmap中使用一个线框在鹰眼视图中标识。当主视图中的视图范围改变时,鹰眼中的线框随之改变,当拖动鹰眼视图中的红线框时,主视图中的视图范围也随之改变。下面开始实现鹰眼功能,添加using esri.arcgis.carto、using esri.arcgis.geometry、using esri.arcgis.display三个引用。首先在axmapcontrol1中视图范围改变时鹰眼窗体要做出对应的响应,即绘制线框并显示,在onextentupdated事件中添加代码如下:private void axmapcontrol1_onextentupdated(object sender, esri.arcgis.controls.imapcontrolevents2_onextentupdatedevent e) /创建鹰眼中线框 ienvelope penv = (ienvelope)e.newenvelope; irectangleelement prectangleele = new rectangleelementclass(); ielement pele = prectangleele as ielement; pele.geometry = penv; /设置线框的边线对象,包括颜色和线宽 irgbcolor pcolor = new rgbcolorclass(); pcolor.red = 255; pcolor.green = 0; pcolor.blue = 0; pcolor.transparency = 255; / 产生一个线符号对象 ilinesymbol poutline = new simplelinesymbolclass(); poutline.width = 2; poutline.color = pcolor; / 设置颜色属性 pcolor.red = 255; pcolor.green = 0; pcolor.blue = 0; pcolor.transparency = 0; / 设置线框填充符号的属性 ifillsymbol pfillsymbol = new simplefillsymbolclass(); pfillsymbol.color = pcolor; pfillsymbol.outline = poutline; ifillshapeelement pfillshapeele = pele as ifillshapeelement; pfillshapeele.symbol = pfillsymbol; / 得到鹰眼视图中的图形元素容器 igraphicscontainer pgra = axmapcontrol2.map as igraphicscontainer; iactiveview pav = pgra as iactiveview; / 在绘制前,清除 axmapcontrol2 中的任何图形元素 pgra.deleteallelements(); / 鹰眼视图中添加线框 pgra.addelement(ielement)pfillshapeele, 0); / 刷新鹰眼 pav.partialrefresh(esriviewdrawphase.esriviewgraphics, null, null); 当鼠标点击鹰眼窗体时,主窗体extent随之改变。在axmapcontrol2的onmousedown事件中添加代码如下:private void axmapcontrol2_onmousedown(object sender, esri.arcgis.controls.imapcontrolevents2_onmousedownevent e) if (this.axmapcontrol2.map.layercount != 0) / 按下鼠标左键移动矩形框 if (e.button = 1) ipoint ppoint = new pointclass(); ppoint.putcoords(e.mapx, e.mapy); ienvelope penvelope = this.axmapcontrol1.extent; penvelope.centerat(ppoint); this.axmapcontrol1.extent = penvelope; this.axmapcontrol1.activeview.partialrefresh(esriviewdrawphase.esriviewgeography, null, null); / 按下鼠标右键绘制矩形框 else if (e.button = 2) ienvelope penvelop = this.axmapcontrol2.trackrectangle(); this.axmapcontrol1.extent = penvelop; this.axmapcontrol1.activeview.partialrefresh(esriviewdrawphase.esriviewgeography, null, null); 当鼠标在鹰眼窗体移动时,主窗体extent随之改变。在axmapcontrol2的onmousemove事件中添加代码如下: private void axmapcontrol2_onmousemove(object sender, esri.arcgis.controls.imapcontrolevents2_onmousemoveevent e) / 如果不是左键按下就直接返回 if (e.button != 1) return; ipoint ppoint = new pointclass(); ppoint.putcoords(e.mapx, e.mapy); this.axmapcontrol1.centerat(ppoint); this.axmapcontrol1.activeview.partialrefresh(esriviewdrawphase.esriviewgeography, null, null); 下面代码用于实现axmapcontrol2与axmapcontrol1的数据的同步更新,获取主视图中视图范围最大的图层作为鹰眼中的视图。这个更新由两部分组成,一个是对axmapcontrol1添加地图文档(mxd文件)的响应,通过axmapcontrol1的onmapreplace事件实现,一个是对axmapcontrol1添加单个图层的响应,通过axmapcontrol1的onfullextentupdated事件实现。我们获取主视图中的视图范围最大的图层写成一个独立的函数,方便调用。 private ilayer getoverviewlayer(imap map) /获取主视图的第一个图层 ilayer player = map.get_layer(0); /遍历其他图层,并比较视图范围的宽度,返回宽度最大的图层 ilayer ptemplayer = null; for (int i = 1; i map.layercount;i+ ) ptemplayer = map.get_layer(i); if (player.areaofinterest.width ptemplayer.areaofinterest.width) player = ptemplayer; return player; 然后在axmapcontrol1的onmapreplaced事件中调用。 private void axmapcontrol1_onmapreplaced(object sender, imapcontrolevents2_onmapreplacedevent e) /获取鹰眼图层 this.axmapcontrol2.addlayer(this.getoverviewlayer(this.axmapcontrol1.map); / 设置 mapcontrol 显示范围至数据的全局范围 this.axmapcontrol2.extent = this.axmapcontrol1.fullextent; / 刷新鹰眼控件地图 this.axmapcontrol2.refresh(); 在axmapcontrol1的onfullextentupdated添加代码,用于实现在主视图添加图层时,实现对鹰眼视图的更新。代码如下: private void axmapcontrol1_onfullextentupdated(object sender, esri.arcgis.controls.imapcontrolevents2_onfullextentupdatedevent e) /获取鹰眼图层 this.axmapcontrol2.addlayer(this.getoverviewlayer(this.axmapcontrol1.map); / 设置 mapcontrol 显示范围至数据的全局范围 this.axmapcontrol2.extent = this.axmapcontrol1.fullextent; / 刷新鹰眼控件地图 this.axmapcontrol2.refresh(); 本例的示例数据无特别要求,使用前面章节实例数据即可。运行程序,添加地图数据,可以在主视图进行相关操作,鹰眼视图同步响应,在鹰眼视图可以移动红线框可以同步更新主视图的视图范围,在鹰眼视图单击右键拉框可以重新绘制红线框,效果如下:图 3鹰眼效果1.3 mygis中添加鹰眼在上一讲中的最后一节,我们创建了一个简单的gis系统mygis,这里,我们讲鹰眼功能嵌入到我们的系统中。在这里我们对实现的思路做一个介绍,请您自己动手完善mygis。首先需要修改一下mygis窗体的控件布局,我们讲鹰眼视图放到图层管理器的下方,需要在控件容器splitercontainer1的panel1中添加一个水平分隔的splitercontainer,然后将图层管理器空间toccontrol和鹰眼视图mapcontrol分别置于上下的容器中,并将其属性dock分别设为fill。另外,在此种窗体布局情况下,直接在toccontrol控件属性中设置伙伴控件无效,如图所示。我们需要在mainform的load事件中为toccontrol设置伙伴控件为axmapcontrol1。添加代码如下: private void form1_load(object sender, eventargs e) /设置axtoccontrol1的伙伴控件 this.axtoccontrol1.setbuddycontrol(axmapcontrol1.object); 图 4 toccontrol控件属性中设置伙伴控件然后依次添加本例中的代码,即可完成,运行效果如下图所示:图 5 mygis中鹰眼的运行效果1.4 小结在本小节中,我们实现了鹰眼功能并讲鹰眼加入了mygis,这部分的重点是鹰眼视图和主视图之间的事件交互。推荐您仔细结合例子程序查看代码,如果需要获得进一步的信息,请查看帮助系统。如果您对这一小节的内容比较熟悉了,就可以开始学习本章最后一小节的内容了。在下一小节中,我们将尝试添加缓冲区分析功能。arcgis engine高级功能开发2 缓冲区分析缓冲区分析指为了识别某一地理实体或空间物体对其周围地物影响度而在其周围建立的具有一定宽度的区域,以确定哪些实体落在了被影响的区域范围之内。缓冲区分析与缓冲区查询不同,缓冲区查询是不破坏原有空间目标的关系,只是检索到该缓冲区范围内涉及到的目标。而缓冲区分析是根据设定的距离条件对一类地物建立缓冲区多边形,存储到一个新的图层中。然后再将新的图层与需要进行缓冲区分析的图层进行叠置分析,得到所需要的结果。因此,缓冲区分析实际上进行了两步的操作,第一步是建立缓冲区图层,第二步是进行叠置剪裁分析。缓冲区分析适用于点、线、面对象,如点状的居民点、线状的河流和面状的作物分布区等,只要地理实体能对周围一定区域形成影响即可使用这种分析方法。图 6点、线、面的缓冲区分析arcgis的arctoolbox中的分析工具提供了缓冲区分析的功能,本节实习我们首先使用geoprocessor方法实现一个简单的缓冲区分析功能,然后将缓冲区分析功能添加到我们的mygis项目中。程序运行前首先需要在d盘下新建一个名为temp的文件夹,存放叠置分析生成的文件。2.1 geoprocessor实现缓冲区分析为了降低开发难度和提高开发效率,arcgis engine中添加了geoprocessor类,使用geoprocessor能帮助用户直接实现一些简单的工具性的功能,所有在arctoolbox中的功能,基本都可以用geoprocessor编程实现。本节我们使用geoprocessor实现缓冲区分析的功能。2.1.1 添加控件新建一个c#.net项目,项目名称为buffer,将form1的名字设置为mainform,并添加toolbarcontrol 、mapcontrol、toccontrol、licencecontrol和button等五个控件。并将toolbarcontrol 、toccontrol的伙伴控件设为mapcontrol,button控件的name属性设定为btnbuffer,text属性设定为“缓冲区分析”。控件布局效果如下图所示。图 7控件布局效果在toolbarcontrol 加载添加数据按钮和地图浏览的功能按钮,如下图所示。图 8添加按钮2.1.2 代码添加及解释首先添加如下四个命名空间的引用。using esri.arcgis.carto;using esri.arcgis.geoprocessor;using esri.arcgis.geoprocessing;using esri.arcgis.esrisystem;在使用geoprocessor工具实现缓冲区分析时,需要首先定义一个geoprocessor对象,因为命名空间“esri.arcgis.geoprocessing”也包含geoprocessor类,为了避免混淆,我们使用命名空间来定义geoprocessor,然后设置geoprocessor中的环境参数,这里我们使用默认参数。然后定义一个操作类buffer,并设置参数,生成缓冲区的参数包含原始图层,缓冲半径和输出路径,最后使用已定义的geoprocessor对象执行即可。双击“生成缓存区”按钮,添加代码如下: private void btnbuffer_click(object sender, eventargs e) /判断mapcontrol中是否包含图层 if (this.axmapcontrol1.layercount = 0) return; /获取mapcontrol中第一个图层 ilayer player = this.axmapcontrol1.map.get_layer(0); /输出路径,可以自行指定 string stroutputpath = d:buffer.shp; /缓冲半径 double dbldistace = 1.0; /获取一个geoprocessor的实例,避免与命名空间geoprocessing中的geoprocessor发生引用错误 esri.arcgis.geoprocessor.geoprocessor gp = new esri.arcgis.geoprocessor.geoprocessor(); /overwriteoutput为真时,输出图层会覆盖当前文件夹下的同名图层 gp.overwriteoutput = true; /创建一个buffer工具的实例 esri.arcgis.analysistools.buffer buffer = new esri.arcgis.analysistools.buffer(player, stroutputpath, dbldistace); /执行缓冲区分析 igeoprocessorresult results = null; results = gp.execute(buffer, null) as igeoprocessorresult; /判断缓冲区是否成功生成 if (results.status != esrijobstatus.esrijobsucceeded) messagebox.show(图层 + player.name + 缓冲区生成失败!); else messagebox.show(缓冲区生成成功!); /将生成图层加入mapcontrol int index = stroutputpath.lastindexof(); this.axmapcontrol1.addshapefile(stroutputpath.substring(0, index), stroutputpath.substring(index); 运行程序,添加一个图层(多个图层时本例中默认选择的图层为第一个图层),点击“生成缓冲区”,运行结果如图。图 9缓冲区生成效果2.1.3 小结本例中,我们使用geoprocessor工具实现了缓冲区分析。从中我们可以得到geoprocessor工具使用的一般方法,在使用geoprocessor时,一般需先定义一个geoprocessor对象,然后设置该对象的参数,如本例中的overwriteoutput,再定义一个具体的操作类,如本例中的buffer类,在设置完操作类的参数后,则通过geoprocessor的excute函数来执行。至此,我们已经实现了一个简单的缓冲区分析的功能,从中我们学习了geoprocessor的使用方法。下一节我们讲对缓冲区份分析功能做进一步的改进,使其具有更强的适用性,并将这个功能添加到mygis中。2.2 mygis中添加缓冲区分析我们在使用缓冲区分析时,需要设定原始的图层,缓冲半径以及生成缓冲区的保存路径。本节我们将在上一节的基础上进一步实现缓冲区分析,实现缓冲图层,缓冲半径和保存路径的可选设置。2.2.1 添加控件打开项目mygis,在mygis的主菜单添加一个新的菜单项“空间分析”,并添加子菜单“缓冲区分析”,name属性修改为“menubuffer”。项目中添加一个新的窗体,名称为“bufferform”,name属性设为“缓冲区分析”,添加四个label、一个combobox、两个textbox、三个button控件,控件属性设置如下:表 1控件属性设置控件类型name属性text属性控件说明label选择图层:label缓冲半径:labellblunit地图单位标示当前地图的地图单位label输出图层:comboboxcbolayers所有图层的名称textboxtxtbufferdistance1.0生成缓冲区的缓冲半径textboxtxtoutputpath缓冲区文件的输出路径,其readonly属性设为truebuttonbtnoutputlayer选择缓冲区文件的输出路径buttonbtnbuffer分析进行缓冲区分析buttonbtncancel取消取消2.2.2 代码添加及解释该项目需添加如下引用:using esri.arcgis.controls;using esri.arcgis.geoprocessor;using esri.arcgis.carto;using esri.arcgis.geoprocessing;using esri.arcgis.esrisystem;首先声明两个成员变量,用于保存地图数据和输出文件的路径。 /接收mapcontrol中的数据 private ihookhelper mhookhelper = new hookhelperclass(); /缓冲区文件输出路径 public string stroutputpath;重写bufferform的构造函数,添加一个参数,用于接收mapcontrol中的数据。 /重写构造函数,添加参数hook,用于传入mapcontrol中的数据 public bufferform(object hook) initializecomponent(); this.mhookhelper.hook = hook; 添加一个自定义函数,用于根据图层名称获取要素图层并返回。 private ifeaturelayer getfeaturelayer(string layername) ifeaturelayer pfeaturelayer = null; /遍历图层,获取与名称匹配的图层 for (int i = 0; i this.mhookhelper.focusmap.layercount; i+) ilayer player = this.mhookhelper.focusmap.get_layer(i); if (player.name = layername) pfeaturelayer = player as ifeaturelayer; if (pfeaturelayer != null) return pfeaturelayer; else return null; bufferform在载入时需要加载当前mapcontrol中的图层名称到cbolayers,读取当前地图的地图单位,设置缓冲区文件的默认输出路径,这里我们将默认输出路径设为“d:temp”。 private void bufferform_load(object sender, eventargs e) /传入数据为空时返回 if (null = mhookhelper | null = mhookhelper.hook | 0 = mhookhelper.focusmap.layercount) return; /获取图层名称并加入cbolayers for (int i = 0; i 0) cbolayers.selectedindex = 0; /设置生成文件的默认输出路径和名称 string tempdir = d:temp; txtoutputpath.text = system.io.path.combine(tempdir, (string)cbolayers.selecteditem + _buffer.shp); /设置默认地图单位 lblunits.text = convert.tostring(mhookhelper.focusmap.mapunits); 双击路径设置按钮,进入代码编辑界面,添加如下代码: 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 = 输出路径; /对话框关闭前还原当前目录 savedlg.restoredirectory = true; savedlg.filename = (string)cbolayers.selecteditem + _buffer.shp; /读取文件输出路径到txtoutputpath dialogresult dr = savedlg.showdialog(); if (dr = dialogresult.ok) txtoutputpath.text = savedlg.filename; 双击“分析”按钮,添加代码如下: private void btnbuffer_click(object sender, eventargs e) /缓冲距离 double bufferdistance; /输入的缓冲距离转换为double double.tryparse(txtbufferdistance.text.tostring(),out bufferdistance); /判断输出路径是否合法 if (!system.io.directory.exists(system.io.path.getdirectoryname(txtoutputpath.text) | .shp != system.io.path.getextension(txtoutputpath.text) messagebox.show(输出路径错误!); return; /判断图层个数 if (mhookhelper.focusmap.layercount = 0) return; /获取图层 ifeaturelayer pfeaturelayer = getfeaturelayer(string)cbolayers.selecteditem); if (null = pfeaturelayer) messagebox.show(图层 + (string)cbolayers.selecteditem + 不存在!rn); return; /获取一个geoprocessor的实例 geoprocessor gp = new geoprocessor(); /overwriteoutput为真时,输出图层会覆盖当前文件夹下的同名图层 gp.overwriteoutput = true; /缓冲区保存路径 stroutputpath = txtoutputpath.text; /创建一个buffer工具的实例 esri.arcgis.analysistools.buffer buffer = new esri.arcgis.analysistools.buffer(pfeaturelayer, stroutputpath, bufferdistance.tostring(); /执行缓冲区分析 igeoprocessorresult results = null; results = (igeoprocessorresult)gp.execute(buffer, null); /判断缓冲区是否成功生成 if (results.status != esrijobstatus.esrijobsucceeded) messagebox.show(图层 + pfeaturelayer.name + 缓冲区生成失败!); else this.dialogresult = dialogresult.ok; messagebox.show(缓冲区生成成功!); 双击“取消”按钮,添加代码如下: private void btncancel_click(object sender, eventargs e) this.dispose(); 进入mygis的主窗体,双击菜单中的“缓冲区分析”,添加代码如下: bufferform bufferform = new bufferform(this.axmapcontrol1.object); if (bufferform.showdialog() = dialogresult.ok) /获取输出文件路径 string strbufferpath = bufferform.stroutputpath; /缓冲区图层载入到mapcontrol int index = strbufferpath.lastindexof(); this.axmapcontrol1.addshapefile(strbufferpath.substring(0, index), strbufferpath.substring(index); 至此,代码编辑完成,运行程序,添加数据usa.mxd,选择图层wind,设置缓冲区半径为0.8,点击“分析”,效果如下图所示。图 10缓冲区分析效果如果运行过程中出现错误“正试图在 os 加载程序锁内执行托管代码。不要尝试在 dllmain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。”,请采用如下方法解决:把vs2005菜单的 调试-异常-managed debuggin assistants-loaderlock 的选中状态去掉即可!如果异常(exception)这一项没有的话,在工具-自定义-命令选项卡,选择左边“调试”,找到右边“异常”拖到菜单上。2.2.3 小结缓冲区分析是gis空间分析的基本功能,这一节我们完成了缓冲区分析的功能,实现了缓冲区分析文件、缓冲半径和输出路径的可选设置,希望您仔细体会并掌握geoprocessor工具开发空间分析功能的基本方法。arcgis engine高级功能开发3 叠置分析叠置分析是gis中一种常见的分析功能,它是将有关主题层组成的各个数据层面进行叠置产生一个新的数据层面,其结果综合了原来两个或多个层面要素所具有的属性,同时叠置分析不仅生成了新的空间关系,而且还将输入的多个数据层的属性联系起来产生了新的属性关系。arcgis中的叠置分析包含union(叠置求并)、intersect(叠置求交)、identify(叠置标识)、erase(叠置擦除)、symmetrical difference (叠置相交取反)、update(叠置更新)等。这一小节,我们以叠置求交为例,介绍叠置分析的开发。叠置求交是保留两个图层公共部分的空间图形,并综合两个叠加图层的属性。如下图,反映了叠置求交的原理。图 11叠置求交示意图本节实习将介绍这种方法实现缓冲区分析,我们首先使用geoprocessor方法实现一个简单的缓冲区分析功能,然后将缓冲区分析功能添加到我们的mygis项目中。同样,arcgis的arctoolbox中的分析工具提供了缓冲区分析的功能,本节实习我们首先使用geoprocessor方法实现一个简单的缓冲区分析功能,然后将缓冲区分析功能添加到我们的mygis项目中。程序运行前首先需要在d盘下新建一个名为temp的文件夹,存放叠置分析生成的文件。3.1 geoprocessor实现叠置分析叠置分析我们同样使用geoprocessor工具来实现。3.1.1 添加控件新建一个c#.net项目,项目名称为overlay,将form1的名字设置为mainform,并添加toolbarcontrol 、mapcontrol、toccontrol、licencecontrol和button等五个控件。并将toolbarcontrol 、toccontrol的伙伴控件设为mapcontrol,button控件的name属性设定为btnintersect,text属性设定为“叠置求交”。控件布局效果如下图所示。图 12控件布局效果在toolbarcontrol 加载添加数据按钮和地图浏览的功能按钮,如下图所示。图 13添加按钮3.1.2 代码添加及解释首先添加如下引用:using esri.arcgis.carto;using esri.arcgis.analysistools;using esri.arcgis.geoprocessor;using esri.arcgis.geoprocessing;与缓冲区分析的实现类似,在使用geoprocessor工具实现叠置

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论