首页 ArcGIS_Engine二次开发——基础篇

ArcGIS_Engine二次开发——基础篇

举报
开通vip

ArcGIS_Engine二次开发——基础篇ArcGISEngine二次开发——基础篇ArcGISEngine二次开发——基础篇1ArcGISEngine二次开发——基础篇1.1第一个简单的ArcGISEngine地图显示程序这个例子将引导您创建第一个简单的地图显示程序,并添加基本的缩放和漫游功能。如果您之前没有接触过ArcGISEngine的开发,那么这个例子是您迈入ArcGISEngine二次开发大门的极好例子,将从零开始引导您一步一步完成任务。1.1.1创建一个新的工程首先打开Mi...

ArcGIS_Engine二次开发——基础篇
ArcGISEngine二次开发——基础篇ArcGISEngine二次开发——基础篇1ArcGISEngine二次开发——基础篇1.1第一个简单的ArcGISEngine地图显示程序这个例子将引导您创建第一个简单的地图显示程序,并添加基本的缩放和漫游功能。如果您之前没有接触过ArcGISEngine的开发,那么这个例子是您迈入ArcGISEngine二次开发大门的极好例子,将从零开始引导您一步一步完成任务。1.1.1创建一个新的 工程 路基工程安全技术交底工程项目施工成本控制工程量增项单年度零星工程技术标正投影法基本原理 首先打开MicrosoftVisualStudio2005,点击菜单栏中的“文件”—>“新建”—>“项目”,在弹出的对话框中选择新建一个VisualC#的Windows应用程序,之后更改项目名称为“地图浏览”,更改文件的路径为个人实习文件夹,点击“确定”即可。图1新建项目对话框选中项目“地图浏览”中的窗体“Form1”,修改其Name属性为“MainForm”,Text属性为“地图浏览”,图2窗体命名1.1.2添加控件及引用点击编译器最左侧的“工具箱”(不存在时可通过“视图”“工具箱”打开),在弹出的选择项中找到“ArcGISWindowsForms”项,单击其中的MapControl,之后在Form1的空白处单击鼠标左键不放并拖拽鼠标,直到调整MapControl到合适的大小再松开鼠标(您也可以直接在工具箱中双击MapControl,该控件则会自动加入到Form1中)。用同样的方法,再将LicenseControl添加到Form1中。图3打开工具箱图4工具箱如果您在工具箱中找不到MapControl,则请依次尝试以下两种解决 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 。首先单击工具栏,待工具箱弹出之后,在工具箱的任意位置上单击鼠标右键,从弹出菜单中选择“重置工具箱”。如果这一步操作之后仍然无法看到MapControl,则在工具箱的任意位置上单击鼠标右键,找到“常规”选项卡,然后在“常规”选项卡上单击鼠标右键,在弹出菜单中单击“选择项(I)…”,在弹出的对话框中选择“.NETFramework组件”,找到“LicenseControl”和“MapControl”,将这两项前的复选框打上勾,最后点击确定即可(如果在“.NETFramework组件”这个面板中找不到这两项,则选择“COM组件”面板,在“ESRILicenseControl”和“ESRIMapControl”前面打勾)。图5重置工具箱图6选择项图7选择工具箱项图8选择工具箱项添加好MapControl和LicenseControl之后,调整Form1和MapControl的位置与大小,如下图所示:图9窗体布局1.1.3添加地图在MapControl上单击鼠标右键,选择“属性”,则会弹出MapControl的属性设置面板,在之前也介绍过,通过这个面板可以完成许多简单的工作。如图所示,点击“Map”面板,之后点击按钮,在弹出的对话框中选择路径为“……\GIS 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 与开发\例子数据\China”,再在此路径下选择“bou2_4p”,点击“Open”。之后在MapControl的属性页上点击“确定”即可。图10“Map”面板至此,我们已经完成了一个最简单的地图显示程序。.点击“启动调试”按钮(或者在“调试”菜单下选择相应命令,或者按键盘的F5键),可以得到如下的运行结果。图11初次运行结果1.1.4添加代码我们没有书写任何代码,就得到了一个最简单的地图显示程序。但这个程序还不能与用户交互,下一步我们需要添加一些代码,让程序能响应用户的鼠标,完成放大和全图显示的功能。选中MapControl控件,单击属性窗口中的事件按钮,可以看到MapControl控件能够响应的所有事件(关于每个事件的详细使用方法等请参见帮助系统),我们可以通过双击对应事件进入代码编辑界面,这里我们选择“OnMouseDown”事件(注:控件的“OnMouseDown”事件也可以通过双击控件直接进入到代码编辑界面),下一步就需要在这个事件中添加响应鼠标的相关代码。图12MapControl控件支持的所有方法请您在axMapControl1的OnMouseDown事件中添加代码,如下所示:privatevoidaxMapControl1_OnMouseDown(objectsender,ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvente){if(e.button==1)this.axMapControl1.Extent=this.axMapControl1.TrackRectangle();elseif(e.button==2)this.axMapControl1.Extent=this.axMapControl1.FullExtent;}再次运行程序,鼠标左键在地图上拉框可以实现地图的放大功能,而右键单击地图则会还原地图的全图显示。图23任意比例尺放大功能如果将代码替换如下,则能实现左键放大,右键漫游的功能。privatevoidaxMapControl1_OnMouseDown(objectsender,ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvente){if(e.button==1)this.axMapControl1.Extent=this.axMapControl1.TrackRectangle();elseif(e.button==2)this.axMapControl1.Pan();}注释:代码中根据e中包含的“button”值来判断鼠标的单击操作是来自何处,若button值为1,则为鼠标左键,2代 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 鼠标右键,4代表鼠标中键。当判断得到是鼠标左键单击时,执行“this.axMapControl1.Extent=this.axMapControl1.TrackRectangle();”该语句调用了“TrackRectangle()”方法,这个方法是在地图上拖拽出一个矩形,之后将这个矩形赋值给当前地图的显示区域(Extent),这样就实现了地图的放大功能。类似的,若鼠标右键单击,则将全图范围赋值给当前的显示范围,实现了地图的全图显示功能。1.1.5小结通过这个例子,我们制作出了一个最简单的地图浏览程序AEMapView,并能响应一些基本的鼠标操作。在MapControl的属性页中,其实还有许多内容您可以尝试,例如在“General”面板中可以直接加入地图文件(*.mxd或者*.mxt),您也可以利用刚才的方式一次性多加入一些图层而不仅仅加入“bou2_4p”一个,同时可以更改各图层的叠放次序,也可以在“Data”面板中设置地图的旋转角度(Rotation)等,您还可以设置MapControl的显示方式,是否支持地图的预览功能,边框样式等等。您可以做一些尝试,看看能得到哪些有趣的结果,这些尝试对您今后熟悉ArcGISEngine的开发是有一定帮助的。如果需要重置MapControl,只需要点击“Data”面板中的“Reset”按钮。当您完成了这个例子,并做了一些积极的尝试之后,您就可以接着学习下一个小节的内容了。1.2属性查询查询是GIS中非常重要的一个功能,下面将分别介绍属性查询和空间查询的制作方法。1.2.1添加控件如果上一小节的工程已经关闭,则将其打开,如果您之后又在MapControl中添加了一些别的数据,请将其删除,只保留一个“bou2_4p”图层,请务必注意这一步,这直接关系到您下面的工作能否顺利进行。用之前讲过添加控件的方式,在窗体中添加一个Label和一个TextBox。将Label控件的“Text”属性修改为“城市名称”,TextBox控件的Name属性修改为txtStateName。控件添加完毕后效果如下:图24添加Label控件和TextBox控件后界面1.2.2添加代码首先添加引用。首先可以在项目的“解决方案资源管理器窗口”中单击展开“引用”选项,查看项目中已添加引用。图25项目已添加“引用”这个项目中我们需要使用“ESRI.ArcGIS.Carto”和“ESRI.ArcGIS.Geodatabase”两个引用项,点击菜单栏上的“项目”—>“添加引用”(或者在“解决方案资源管理器窗口”中右击“引用”,在弹出菜单中选择“添加引用”),在弹出的对话框中选择需要添加的引用,同时选择“ESRI.ArcGIS.Carto”和“ESRI.ArcGIS.Geodatabase”(选择的时候按下Ctrl键以同时选择多个),这里“ESRI.ArcGIS.Carto”在添加MapControl控件时已自动添加,我们只添加“ESRI.ArcGIS.Geodatabase”,点击确定。图26添加引用对话框之后双击TextBox控件,进入代码编辑界面。在代码编辑区域的命名空间(namespace)的上方输入以下内容:usingESRI.ArcGIS.Carto;usingESRI.ArcGIS.Geodatabase;如下图所示:图27引用添加位置之后在控件TextBox的事件中选择KeyUp,在KeyUp事件中添加以下代码:图28KeyUp方法privatevoidtxtStateName_KeyUp(objectsender,KeyEventArgse){//判断鼠标键值,如果Enter键按下抬起后,进入查询if(e.KeyCode==Keys.Enter){//定义图层,要素游标,查询过滤器,要素IFeatureLayerpFeatureLayer;IFeatureCursorpFeatureCursor;IQueryFilterpQueryFilter;IFeaturepFeature;//获取图层pFeatureLayer=this.axMapControl1.Map.get_Layer(0)asIFeatureLayer;//如果图层名称不是states,程序退出if(pFeatureLayer.Name!="bou2_4p")return;//清除上次查询结果this.axMapControl1.Map.ClearSelection();//pQueryFilter的实例化pQueryFilter=newQueryFilterClass();//设置查询过滤条件pQueryFilter.WhereClause="NAME='"+txtStateName.Text+"'";//查询pFeatureCursor=pFeatureLayer.Search(pQueryFilter,true);//获取查询到的要素pFeature=pFeatureCursor.NextFeature();//判断是否获取到要素if(pFeature!=null){//选择要素this.axMapControl1.Map.SelectFeature(pFeatureLayer,pFeature);//放大到要素this.axMapControl1.Extent=pFeature.Shape.Envelope;}else{//没有得到pFeature的提示MessageBox.Show("没有找到名为"+txtStateName.Text+"的省","提示");}}}运行程序,分别向编辑框中输入“吉林省”和“长春省”,键入回车,如下图所示:图29吉林省查询结果图30长春省查询结果注释:if(e.KeyCode==Keys.Enter)上述代码是一个判断语句,即当用户输入回车的时候,开始进行查询。下面两行代码是定义查询的范围,默认为上一小节中添加的图层“bou2_4p”,如果找不到这个图层则自动退出。//获取图层pFeatureLayer=this.axMapControl1.Map.get_Layer(0)asIFeatureLayer;//如果图层名称不是states,程序退出if(pFeatureLayer.Name!="bou2_4p")return;//清除上次查询结果this.axMapControl1.Map.ClearSelection();下面部分是生成一个新的查询器,选择条件(WhereClause)就是检索是否有与用户输入相符的州,并将结果从查询得到的pCursor中读取出来。//pQueryFilter的实例化pQueryFilter=newQueryFilterClass();//设置查询过滤条件pQueryFilter.WhereClause="NAME='"+txtStateName.Text+"'";//查询pFeatureCursor=pFeatureLayer.Search(pQueryFilter,true);//获取查询到的要素pFeature=pFeatureCursor.NextFeature();下面部分是一个判断语句,若查询得到的结果为空,则刷新地图,弹出对话框通知用户没有查询到结果,并退出程序。如果查询得到的结果不为空,则将这个结果加入地图的选择集,并将地图的显示范围定为查询结果的外轮廓,这样得到的州将高亮显示同时居中放大到屏幕中心。//判断是否获取到要素if(pFeature!=null){//选择要素this.axMapControl1.Map.SelectFeature(pFeatureLayer,pFeature);//放大到要素this.axMapControl1.Extent=pFeature.Shape.Envelope;}else{//没有得到pFeature的提示MessageBox.Show("没有找到名为"+txtStateName.Text+"的省","提示");}1.2.3小结这一部分中,我们接触到了基本的属性查询。但是在这个例子中,我们不能实现对属性表中任意属性字段的查询(在这个程序中,我们只能查询省名——NAME,而不能对别的字段进行查询),而且这个查询不支持模糊查询。为了使查询变的更加丰富,更加人性化,请您参考IQueryFilter接口中WhereClause属性的设置方法,拓展WhereClause可以得到许多有趣的结果。在书写代码的过程中,对任何有疑问的地方,或者您想要拓展的位置,都可以在帮助系统中查询相关的接口和属性,查看最原始的定义,帮助系统中的解释和定义对于您熟悉ArcObjects,熟悉ArcGISEngine的二次开发以及后续的工作都是十分重要的,请一定不要忽视这个环节。如果您已经尝试了一些变化,或者对本小节的内容比较熟悉了,则可以进入下一小节的学习。1.3空间查询上一小节我们已经学习了如何进行属性查询,在这一小节中,我们将继续学习GIS中的另一种查询方式——空间查询,其中有点查询、线查询、矩形查询、圆查询。本节我们将空间查询的方法抽象为一个独立的函数,这个函数中我们将根据不同的空间查询方式,返回查询得到的一个或多个要素的名称并在地图上高亮显示。1.3.1添加控件新建一个C#.Net工程,向工程中添加控件,如下图所示:图31窗体布局其中包括MapControl,4个Button,一个TextBox。属性设置如下:窗体及控件属性设置 类型 Name Text 用途 Form MainForm 空间查询 主窗体 TextBox txtTips 请在地图上选取地物! 系统操作提示 Button btnPointQuery 点查询 点查询 Button btnLineQuery 线查询 线查询 Button btnRectQuery 矩形查询 矩形查询 Button btnCircleQuery 圆查询 圆查询通过在控件属性中添加地图的方法,向Mapcontrol中添加例子数据。(例子数据是位于China文件夹下的bou2_4p)如下图所示:图32添加数据下面我们在MainForm的代码页添加空间查询的函数。本例中我们需要添加ESRI.ArcGIS.Carto、ESRI.ArcGIS.Geometry、ESRI.ArcGIS.Geodatabase、ESRI.ArcGIS.Controls四个个命名空间。我们仍然需要上节中的ConvertPixelToMapUnits(IActiveViewactiveView,doublepixelUnits)函数,请自行添加。1.3.2添加代码先在类中添加一个公共函数,用来根据屏幕像素计算实际的地理距离。///<summary>///根据屏幕像素计算实际的地理距离///</summary>///<paramname="activeView">屏幕视图</param>///<paramname="pixelUnits">像素个数</param>///<returns></returns>privatedoubleConvertPixelToMapUnits(IActiveViewactiveView,doublepixelUnits){doublerealWorldDiaplayExtent;intpixelExtent;doublesizeOfOnePixel;doublemapUnits;//获取设备中视图显示宽度,即像素个数pixelExtent=activeView.ScreenDisplay.DisplayTransformation.get_DeviceFrame().right-activeView.ScreenDisplay.DisplayTransformation.get_DeviceFrame().left;//获取地图坐标系中地图显示范围realWorldDiaplayExtent=activeView.ScreenDisplay.DisplayTransformation.VisibleBounds.Width;//每个像素大小代表的实际距离sizeOfOnePixel=realWorldDiaplayExtent/pixelExtent;//地理距离mapUnits=pixelUnits*sizeOfOnePixel;returnmapUnits;}然后添加空间查询的方法,空间查询函数代码如下:///<summary>///空间查询///</summary>///<paramname="mapControl">MapControl</param>///<paramname="geometry">空间查询方式</param>///<paramname="fieldName">字段名称</param>///<returns>查询得到的要素名称</returns>privatestringQuerySpatial(AxMapControlmapControl,IGeometrygeometry,stringfieldName){//本例添加一个图层进行查询,多个图层时返回if(mapControl.LayerCount>1)returnnull;//清除已有选择mapControl.Map.ClearSelection();//查询得到的要素名称stringstrNames=null;IFeatureLayerpFeatureLayer;IFeatureClasspFeatureClass;//获取图层和要素类,为空时返回pFeatureLayer=mapControl.Map.get_Layer(0)asIFeatureLayer;pFeatureClass=pFeatureLayer.FeatureClass;if(pFeatureClass==null)returnnull;//初始化空间过滤器ISpatialFilterpSpatialFilter;pSpatialFilter=newSpatialFilterClass();pSpatialFilter.Geometry=geometry;//根据图层类型选择缓冲方式switch(pFeatureClass.ShapeType){caseesriGeometryType.esriGeometryPoint:pSpatialFilter.SpatialRel=esriSpatialRelEnum.esriSpatialRelContains;break;caseesriGeometryType.esriGeometryPolyline:pSpatialFilter.SpatialRel=esriSpatialRelEnum.esriSpatialRelCrosses;break;caseesriGeometryType.esriGeometryPolygon:pSpatialFilter.SpatialRel=esriSpatialRelEnum.esriSpatialRelIntersects;break;}//定义空间过滤器的空间字段pSpatialFilter.GeometryField=pFeatureClass.ShapeFieldName;IQueryFilterpQueryFilter;IFeatureCursorpFeatureCursor;IFeaturepFeature;//利用要素过滤器查询要素pQueryFilter=pSpatialFilterasIQueryFilter;pFeatureCursor=pFeatureLayer.Search(pQueryFilter,true);pFeature=pFeatureCursor.NextFeature();intfieldIndex;while(pFeature!=null){//选择指定要素fieldIndex=pFeature.Fields.FindField(fieldName);//获取要素名称strNames=strNames+pFeature.get_Value(fieldIndex)+";";//高亮选中要素mapControl.Map.SelectFeature((ILayer)pFeatureLayer,pFeature);mapControl.ActiveView.Refresh();pFeature=pFeatureCursor.NextFeature();}returnstrNames;}定义鼠标标记的成员变量mMouseFlag。在设计页面双击点查询按钮,进入点击按钮响应事件填写如下代码。privatevoidbtnPointQuery_Click(objectsender,EventArgse){mMouseFlag=1;this.axMapControl1.MousePointer=esriControlsMousePointer.esriPointerCrosshair;}相应的线查询、矩形查询、圆查询添加同样的代码,但nMouseFlag得值要有所改变。线查询:nMouseFlag=2矩形查询:nMouseFlag=3圆查询:nMouseFlag=4为MapControl控件添加OnMouseDown事件,填入以下代码privatevoidaxMapControl1_OnMouseDown(objectsender,IMapControlEvents2_OnMouseDownEvente){//记录查询到的要素名称stringstrNames="查询到的要素为:";//查询的字段名称stringstrFieldName="NAME";//点查询if(mMouseFlag==1){IActiveViewpActiveView;IPointpPoint;doublelength;//获取视图范围pActiveView=this.axMapControl1.ActiveView;//获取鼠标点击屏幕坐标pPoint=pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x,e.y);//屏幕距离转换为地图距离length=ConvertPixelToMapUnits(pActiveView,2);ITopologicalOperatorpTopoOperator;IGeometrypGeoBuffer;//根据缓冲半径生成空间过滤器pTopoOperator=pPointasITopologicalOperator;pGeoBuffer=pTopoOperator.Buffer(length);strNames=strNames+QuerySpatial(this.axMapControl1,pGeoBuffer,strFieldName);}elseif(mMouseFlag==2)//线查询{strNames=strNames+QuerySpatial(this.axMapControl1,this.axMapControl1.TrackLine(),strFieldName);}elseif(mMouseFlag==3)//矩形查询{strNames=strNames+QuerySpatial(this.axMapControl1,this.axMapControl1.TrackRectangle(),strFieldName);}elseif(mMouseFlag==4)//圆查询{strNames=strNames+QuerySpatial(this.axMapControl1,this.axMapControl1.TrackCircle(),strFieldName);}else{strNames="未得到空间要素!";}//提示框显示提示this.txtTips.Text=strNames;}注释:距离转换函数请参看程序注释。Button的Click事件中是将nMouseFlag设置为1,并将鼠标在MapControl上的形状改变为十字丝状。//获取视图范围pActiveView=this.axMapControl1.ActiveView;//获取鼠标点击屏幕坐标pPoint=pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x,e.y);//屏幕距离转换为地图距离length=ConvertPixelToMapUnits(pActiveView,2);上述代码是在MapControl的OnMouseDown事件中,当您单击鼠标左键的时候,获取点击位置的屏幕坐标,并将屏幕上的两个像素大小的距离转换成地图上的距离,作为查询的缓存半径。//根据缓冲半径生成空间过滤器pTopoOperator=pPointasITopologicalOperator;pGeoBuffer=pTopoOperator.Buffer(length);pSpatialFilter=newSpatialFilterClass();pSpatialFilter.Geometry=pGeoBuffer;上述代码是以鼠标的点击位置,以缓冲距离length为半径,生成一个缓冲区。pSpatialFilter=newSpatialFilterClass();pSpatialFilter.Geometry=pGeoBuffer;//根据图层类型选择缓冲方式switch(pFeatureClass.ShapeType){caseesriGeometryType.esriGeometryPoint:pSpatialFilter.SpatialRel=esriSpatialRelEnum.esriSpatialRelContains;break;caseesriGeometryType.esriGeometryPolyline:pSpatialFilter.SpatialRel=esriSpatialRelEnum.esriSpatialRelCrosses;break;caseesriGeometryType.esriGeometryPolygon:pSpatialFilter.SpatialRel=esriSpatialRelEnum.esriSpatialRelIntersects;break;}//定义空间过滤器的空间字段pSpatialFilter.GeometryField=pFeatureClass.ShapeFieldName;上述代码是设置pSpatialFilter的各项参数,供后续查询,包括空间查询的几何形状(之前生成的缓冲区),空间查询的方式(相交,包含等)以及Shape字段。fieldIndex=pFeature.Fields.FindField("NAME");MessageBox.Show("查找到“"+pFeature.get_Value(fieldIndex)+"”","提示");这两句代码是找出“NAME”所在的列数,并将其显示出来。点击运行,运行效果如下图所示:图33线查询运行效果仔细研读代码,您会发现,在这部分中我们并没有用到什么新的知识,只是在结构上做了调整,应为空间查询都是需要使用一个IGeometry对象进行空间求交进行查询的。所以我们将公共的代码放在公共的模块中进行调用。有心的同学可能发现,我们为了判断用户在MapControl上的操作,我们引入了一个全局变量nMouseFlag,程序中多一个全局变量,对程序的结构的封闭性就有所破坏,能不能去掉这个全局变量而是Mapcontrol自主判断是哪个功能进行操作呢?答案是肯定的,我们可以使用BaseCommand和BaseTool来完成这个工作,详细的用法在3.4和3.5小节将会介绍。1.3.3小结在这一小节中,我们学习了如何进行简单的空间查询。空间查询不仅包括点查询,还包括线查询,矩形查询,多边形查询等(为了实现这些功能,可以参考MapControl中的TrackRectangle等方法)。对于这一小节的代码,强烈建议您参看帮助系统中对相关接口的解释和定义,以进一步熟悉接口的使用,这对后面的学习以及掌握ArcGISEngine二次开发是极有好处的。如果您对这一部分比较熟悉了,可以进入下一小节。在第四章中,我们介绍了控件命令(ControlCommands),并提到ArcGISEngine允许用户自定义开发一些控件命令,在下两小节中,我们将具体学习如何开发。1.4BaseCommand开发实例在这一小节和下一小节中中,我们将学习ArcEngine中基于BaseCommand和BaseTool的功能开发步骤。基于BaseCommand的功能实现与Button的功能类似,是当鼠标点击按钮的时候,MapControl控件会对其中的命令做出相应响应而无需额外的操作,如ArcMap中的居中放大FixedZoomIn,全图FullExtent等。在这一小节中,我们将基于BaseCommand制作一个“固定比例尺放大”的按钮,当鼠标单击按钮时,地图将居中放大一倍。1.4.1添加控件如果上一小节的程序已经关闭,则重新打开,同时保证MapControl控件中加载了至少一个图层。在主窗体(MapViewForm)中添加一个Button,将其Name属性改为btnFixedZoomIn,Text属性更改为“居中放大”。1.4.2添加BaseCommand点击菜单栏上的“项目”—>“添加类”,弹出以下对话框。图34添加新项对话框如上图所示,在类别中选择ArcGIS项,在右侧的 模板 个人简介word模板免费下载关于员工迟到处罚通告模板康奈尔office模板下载康奈尔 笔记本 模板 下载软件方案模板免费下载 中选择“BaseCommand”项,并在名称中将其更改为“FixedZoomIn”,点击添加,出现如下对话框。图35类别选择向导我们这个命令是用于MapControl控件的,所以在选择项中选择“ArcMap,MapControlorPageLayoutControlCommand”或者“MapControlorPageLayoutControlCommand”,这里我们选择后者,点击OK。1.4.3添加代码双击解决方案资源管理器中的FixedZoomIn.cs项,进入该类的代码编写界面。首先按照前几节介绍过的方法,加入引用“ESRI.ArcGIS.Geometry”,并在该类的最上方添加如下代码:usingESRI.ArcGIS.Carto;usingESRI.ArcGIS.Geometry;将base.m_caption、base.m_toolTip更改为“居中放大”,将base.m_name更改为“FixedZoomIn”。之后在OnClick()函数中添加如下代码:publicoverridevoidOnClick(){//TODO:AddFixedZoomIn.OnClickimplementation//获取当前视图范围IActiveViewpActiveView=m_hookHelper.ActiveView;IEnvelopepEnvelope=pActiveView.Extent;//扩大视图范围并刷新视图pEnvelope.Expand(0.5,0.5,true);pActiveView.Extent=pEnvelope;pActiveView.Refresh();}转到主窗体(MapViewForm),双击“居中放大”按钮,进入该按钮Click事件相应函数,添加如下代码:privatevoidbtnZoomIn_Click(objectsender,EventArgse){//声明与初始化FixedZoomInfixedZoomin=newFixedZoomIn();//与MapControl关联fixedZoomin.OnCreate(this.axMapControl1.Object);fixedZoomin.OnClick();}1.4.4运行运行程序,点击“居中放大”时,地图会放大一倍。点查询功能依然可用,如下图:图36程序运行结果1.4.5小结在这一小节中,我们学习到了如何制作一个BaseCommand。使用BaseCommand的好处主要有,首先按照面向对象的思想,居中放大这个功能已经被封装在我们自己书写的类中,若是以后需要再将这个功能移植到别的程序,或者由多个程序员共同完成一个程序时,只需要将这个类复制到相关工程下,稍作调整即可运行;其次,这样做可以是代码更易读,而且当需要完成许多不同的功能时,这种方法的优势就体现出来了,因为我们不需要再单独设立一个MouseFlag变量来判断具体用户点击了哪个按钮,MapControl的OnMouseDown事件中也无需再添加冗长的代码,而是分散到各类中,增强了程序的稳定性。在新建FixedZoomIn类的同时,我们发现还会附带生成一个FixedZoomIn.bmp位图文件,您可以双击这个图标以做相关编辑更改工作,也可以用自己的图标来替换(注意保持文件名一致)。这个图标的作用,是在使用ToolbarControl的时候,用于显示按钮图标的。您可以尝试着在工程中加入一根ToolbarControl,并使用AddItem方法添加我们写好的这个类,看能否得到一样的结果。使用ArcEngine自带BaseCommand基类,可以方便的开发出相关的Command按钮,从这个实例我们可以看出,根据Command按钮随鼠标点击MapControl及时响应的特性,我们一般只需要重载BaseCommand的OnClick()函数即可。然后在功能的实现处首先调用OnCreate()函数实现与MapControl的关联,调用OnClick()函数实现功能响应。这样有效的提高了我们进行功能开发的效率。其实,对于一些基本的地图操作Command的功能,ArcEngine进行了完整的封装,我们在使用时可以直接使用ArcEngine的封装类进行实例化。仍以“固定比例尺放大”为例,我们可以在“居中放大”按钮的Click事件中直接使用ArcEngine的封装类实现(注意,在这个示例中需要添加“ESRI.ArcGIS.SystemUI”和“ESRI.ArcGIS.Controls”的引用),代码如下:ICommandcommand=newControlsMapZoomInFixedCommandClass();command.OnCreate(this.axMapControl1.Object);command.OnClick();这种方法比我们基于BaseCommand的开发方法更加简便,我们在此介绍的目的是为了让大家掌握这种基本的开发方法,方便用于其他Command功能的开发。如果您对本小节的内容比较熟悉,也做了一些积极的尝试,那么您可以进入下一小节的学习。在下一小节中我们将学习BaseTool的开发方法。1.5BaseTool开发实例经过上一小节的学习,我们了解到了如何自定义BaseCommand来拓展ArcGIS的应用。我们将学习基于BaseTool的自定义功能开发,BaseTool与BaseCommand有些相似的地方,它们都是点击之后可以对MapControl控件做相应的操作,但是BaseCommand点击之后MapControl会直接予以相应,不需要额外的操作,而对于BaseTool来说,点击该功能之后,只是开启一个交互的过程,需要用户再用鼠标、键盘等对地图做进一步交互式的操作,MapControl控件才会予以相应,如ArcMap中的放大ZoomIn、漫游Pan等。为了实现BaseTool与BaseCommand功能实现的差异,在这一小节中,我们将剖析ArcMap的放大(ZoomIn)功能,并利用BaseTool进行实现。1.5.1打开工程我们这里需要在上一小节的基础上继续完善,如果您已经将MapView关闭,请重新打开。在主窗体(MapViewForm)中添加一个Button,将其Name属性改为btnZoomIn,Text属性更改为“拉框放大”。3.5.2添加BaseTool在菜单栏上选择“项目”——“添加类”,出现如下对话框:图37添加新项对话框在类别中选中ArcGIS,在模板中选择BaseTool,并将名称更改为“ZoomIn”,点击添加,出现如下对话框:图38类别选择向导我们这个工具是要用于MapControl,仍选择“MapControlorPageLayoutControlCommand”,点击OK。1.5.2添加代码双击解决方案资源管理器中的ZoomIn.cs,进入该类的代码编写界面。首先添加ESRI.ArcGIS.Carto、ESRI.ArcGIS.Geodatabase、ESRI.ArcGIS.Geometry、ESRI.ArcGIS..Display四个引用,类似的,将base.m_caption、base.m_toolTip更改为“拉框放大”,将base.m_name更改为“ZoomIn”。我们简单分析一下拉框放大的执行过程,点击“拉框放大”按钮后,鼠标在MapControl的视图中的拉框过程可以分解为三个事件,鼠标在视图上的按下(MouseDown),鼠标按下在视图上的移动(MouseMove),鼠标放开(MouseUp),我们需要在鼠标按下时刻和放开时刻记录鼠标点击的坐标,然后可以得到一个新的视图范围,完成放大操作。下面添加代码,首先我们需要在这个类中定义三个成员变量,三个成员变量的功能如注释所示。//记录鼠标位置privateIPointm_point;//标记MouseDown是否发生privateBooleanm_isMouseDown;//追踪鼠标移动产生新的EnvelopeprivateINewEnvelopeFeedbackm_feedBack;在ZoomIn.cs类中的OnMouseDown函数中添加如下代码:publicoverridevoidOnMouseDown(intButton,intShift,intX,intY){//当前地图视图为空时返回if(m_hookHelper.ActiveView==null)return;//获取鼠标点击位置m_point=m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X,Y);m_isMouseDown=true;}在ZoomIn.cs类中的OnMouseMove函数中添加如下代码:publicoverridevoidOnMouseMove(intButton,intShift,intX,intY){//MouseDown为发生时返回if(!m_isMouseDown)return;IActiveViewpActiveView=m_hookHelper.ActiveView;//m_feedBack追踪鼠标移动if(m_feedBack==null){m_feedBack=newNewEnvelopeFeedbackClass();m_feedBack.Display=pActiveView.ScreenDisplay;//开始追踪m_feedBack.Start(m_point);}//追踪鼠标移动位置m_feedBack.MoveTo(pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X,Y));}在ZoomIn.cs类中的OnMouseUp函数中添加如下代码:publicoverridevoidOnMouseUp(intButton,intShift,intX,intY){//MouseDown为发生时返回if(!m_isMouseDown)return;IActiveViewpActiveView=m_hookHelper.ActiveView;//获取MouseUp发生时的范围并放大IEnvelopepEnvelope;if(m_feedBack==null)//鼠标未拉框时进行固定比例尺放大{pEnvelope=pActiveView.Extent;pEnvelope.Expand(0.5,0.5,true);pEnvelope.CenterAt(m_point);}else{//停止追踪pEnvelope=m_feedBack.Stop();//判断新的范围的高度和宽度是否为零if(pEnvelope.Width==0||pEnvelope.Height==0){m_feedBack=null;m_isMouseDown=false;}}//获取新的范围pActiveView.Extent=pEnvelope;//刷新视图pActiveView.Refresh();m_feedBack=null;m_isMouseDown=false;}再进入MapViewForm窗体的代码界面,定义成员变量privateZoomInmZoomIn=null;双击MapViewForm窗体上的“拉框放大”按钮,进入Click事件响应函数,将其中的代码删除,用下列代码替代:privatevoidbtnZoomIn_Click(objectsender,EventArgse){//初始化mZoomIn=newZoomIn();//与MapControl的关联mZoomIn.OnCreate(this.axMapControl1.Object);//设置鼠标形状this.axMapControl1.MousePointer=esriControlsMousePointer.esriPointerZoomIn;}将MapControl控件的OnMouseDown响应函数中的内容全部删除,添加代码如下:if(mZoomIn!=null)mZoomIn.OnMouseDown(e.button,e.shift,e.x,e.y);在MapControl控件的OnMouseMove响应函数中添加代码如下:if(mZoomIn!=null)mZoomIn.OnMouseMove(e.button,e.shift,e.x,e.y);在MapControl控件的OnMouseUp响应函数中添加代码如下:if(mZoomIn!=null)mZoomIn.OnMouseUp(e.button,e.shift,e.x,e.y);1.5.3运行图39程序运行结果如上图所示,首先点击“拉框放大”按钮,然后在MapControl中按下
本文档为【ArcGIS_Engine二次开发——基础篇】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_684321
暂无简介~
格式:doc
大小:1MB
软件:Word
页数:60
分类:互联网
上传时间:2014-03-05
浏览量:83