arcgis-engine二次开发讲义


ArcGIS Engine 二次开发实习初级讲义 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 2 - 目录 1 ArcGIS、ArcObjects 和 ArcGIS Engine 简介....................................................................- 3 - 1.1 ArcGIS 简介 ................................................................................................................- 3 - 1.2 ArcObjects 简介 ..........................................................................................................- 4 - 1.3 ArcGIS Engine 简介....................................................................................................- 5 - 2 ArcGIS 控件介绍....................................................................................................................- 7 - 2.1 ArcGIS 控件简介 ........................................................................................................- 7 - 2.2 重要控件简介...............................................................................................................- 9 - 3 ArcGIS Engine 二次开发入门 ............................................................................................- 16 - 3.1 ArcGIS Engine 开发起步——第一个简单的地图显示程序 ..................................- 16 - 3.2 属性查询....................................................................................................................- 23 - 3.3 空间查询....................................................................................................................- 27 - 3.4 BaseCommand 开发实例 ..........................................................................................- 36 - 3.5 BaseTool 开发实例....................................................................................................- 38 - 3.6 通过代码添加图层.....................................................................................................- 42 - 3.7 基于比例尺显示地图.................................................................................................- 44 - 3.8 构建一个简单的 GIS 应用........................................................................................- 46 - 4.问题解决方法及帮助文档的使用........................................................................................- 58 - 4.1 使用 ArcObjects 开发帮助系统...............................................................................- 58 - 4.2 阅读对象模型图(Object Model Diagram).........................................................- 62 - Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 3 - 1 ArcGIS、ArcObjects 和 ArcGIS Engine 简介 1.1 ArcGIS 简介 ArcGIS 提供了一个可伸缩的框架,可以为独立用户或者多用户,既可以在桌面端也可 以在服务器端提供 GIS。ArcGIS 9 是用来构建一个完整 GIS 应用的 GIS 软件产品集成。它 是基于共享的 GIS 软件组件——ArcObjects。ArcGIS 9 由以下四部分组成:  ArcGIS Desktop——高级 GIS 应用的集成  ArcGIS Engine——根据应用程序接口来构建基本应用的嵌入式 GIS 组件库  ArcGIS Server——在企业级或者网络框架下构建服务器端 GIS 应用的平台,用来 构建 Web 服务和 Web 应用  ArcIMS——通过公开的因特网协议来发布地图、数据和元数据的 GIS Web 服务器 图 1 ArcGIS 产品结构图 每一个 GIS 框架同样包含 ArcSDE 网关,这是在关系数据库(RDBMS)上组织地理数 据的接口。 ArcGIS 是构建地理信息系统的平台。ArcGIS 9 在地理数据处理、3D 可视化表达和开 发工具方面做了新的扩展。两个新的产品——ArcGIS Engine 和 ArcGIS Server 在这个版本 中发布,是 ArcGIS 成为一个应用程序及服务端开发的完整产品。  使用 ArcGIS 能够开发出一系列的产品,开发者可以:  配置/定制 ArcGIS 的应用,例如 ArcMap 和 ArcCatalog  扩展 ArcGIS 的结构和数据模型  利用 ArcGIS Engine 在其他应用程序中嵌入地图和 GIS 功能 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 4 -  使用 ArcGIS Engine 构建并部署桌面版应用程序  使用 ArcGIS Server 构建 Web 服务和应用 ArcGIS 系列产品是通过称之为 ArcObjects 的软件组件加以构建和扩展的。ArcObjects 包括一系列不同的程序组件,从高度封装的组件(例如独立的 geometry objects)到低级组 件(例如能够同已有的 ArcMap 文档集成的地图组件)。这些组件为开发者集成了大量的 GIS 功能。 ArcGIS 9 的全线产品都具备开发功能(Engine,Server 和 Desktop)。作为一个开发 者,您能够使用标准程序框架结合 ArcObjects 来扩张 ArcGIS Desktop;能够用 ArcGIS Engine 定制应用;能够使用 ArcGIS Server 构建企业级的 GIS 应用。 图 2 ArcGIS 开发结构图 ArcGIS Desktop 包含了一些列的 Windows 桌面应用程序(例如,地图、目录、工具箱、 地球方面的应用)。ArcGIS Desktop 包含了三种功能级别(ArcView,ArcEditor 和 ArcInfo), 使用 ArcGIS Desktop 开发包能够进行客户化和扩展。 ArcGIS Desktop 的软件开发包(software developer kit,SDK)包含在 ArcView, ArcEditor 和 ArcInfo 内,支持 COM(Component Objects Model,组件对象模型)和.NET 程序框架。许多开发者利用 Desktop SDK 扩展功能,创建新的 GIS 工具,定制用户界面, 完善 ArcGIS Desktop 应用中专业 GIS 产品的扩展功能。 ArcGIS Server 不仅定义和实现了一系列标准的 GIS Web 服务(例如,地图、数据访 问、地理编码等),同时还支持利用 ArcObjects 进行企业级的服务端应用开发。 ArcGIS Server 开发包让开发者能构建 GIS 服务器用来向多用户提供可供访问的 GIS 功能,能通过客户端对大型 GIS 中央服务器进行处理,能构建和分发 GIS Web 应用,能进 行分布式 GIS 运算。 1.2 ArcObjects 简介 ArcObjects 是 ArcGIS Desktop 的开发平台。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 5 - ArcGIS Desktop 是一系列 GIS 软件系统:ArcInfo,ArcEditor 和 ArcView。这些系统 服务于 GIS,例如地理数据组织、控件编辑、分级可视化等功能。 ArcGIS Desktop 系统包含一系列的应用,例如 ArcCatalog、ArcMap、ArcToolBox 和 ArcScene,并且能够集成大量不同的扩展产品,例如 ArcGIS Spatial Analyst(空间分析模 块),ArcGIS Geostatistical Analyst(地理统计分析模块),ArcGIS 3D Analyst(三维分析 模块)等。 ArcObjects 是使用微软的组件对象模型(Component Objects Model,COM)书写。 因此,凡是支持 COM 标准的开发语言都能使用 ArcObjects。您能向 ESRI(Environment System Research Institute,环境系统研究所)的开发者一样,使用同样的方式来扩展 ArcObjects 中的任何一部分。 1.3 ArcGIS Engine 简介 ArcGIS Engine 是开发者用来构建应用程序的一整套嵌入式 GIS 组件。使用 ArcGIS Engine,您可以将一些 GIS 功能嵌入到已有的应用程序中,这包括 Microsoft Office 产品, 例如Word 和 Excel,建造有针对性的客户应用程序用来将高级 GIS系统与他人分享。ArcGIS Engine 由一个软件开发包(software development kit,SDK)和一个给所有 ArcGIS 应用 提供平台的运行许可(runtime)构成。 构成 ArcGIS Engine 的五部分分别如下: 1)基本服务——几乎任何 GIS 应用都需要的核心 GIS ArcObjects,例如几何 (geometry),显示(display)等。 2)数据访问——ArcGIS Engine 提供许多栅格和矢量数据的访问方式,包括与 geodatabase 相当的能力和灵活性。 3)地图表达——ArcObjects 使用符号、注记和专题地图来生成和表达地图。 4)开发组件——用来快速定制应用开发程序的高度封装用户接口以及开发过程中全面 的帮助系统。 5)运行许可——ArcGIS Engine 运行许可可以部署标准功能或者加入一些附加的高级 功能。 这中间除了运行许可之外的任何一部分,都打包集成到 ArcGIS Engine 开发包(SDK) 中。ArcGIS Engine 运行许可及其选项,尽管是开发完整的 GIS 应用程序中的一部分,但 包含了应用部署,所以被单独打包。 1.3.1 ArcGIS Engine Software Developer Kit ArcGIS Engine SDK 是用来开发和部署 GIS 及地图方面应用程序的组件化软件开发产 品。ArcGIS Engine SDK 不是终端产品而是共应用开发者使用的软件包。它能构建基本的 地图浏览或者全面的、动态的 GIS 编辑工具。使用 ArcGIS Engine SDK,作为开发者,您 在定制地图功能接口方面有空前的自由。您可以使用许多 API 中的一些来构建独一无二的 应用程序或者将 ArcGIS Engine 组建与其他软件组建整合,来实现地图和用户需要的其他 信息之间的完美结合。 使用 ArcGIS Engine,地图既能够作为应用程序的核心,也可以作为一个可选项。例如, 如果您的应用主要是数据库中的商务信息,当您查询数据库的时候,ArcGIS Engine 能够将 您感兴趣的商业信息在地图上高亮显示定位出来。 ArcGIS Engine SDK 提供了大量的 GIS 组件,或者称为 ArcObjects,按照之前的介绍, 包括基本服务、数据访问和地图表达。之前提到的 ArcGIS Engine 的第四部分,也就是开 发组件,也包含在 SDK 中间。这些都是用来构建一个高质量地图接口的开发控件。下面列 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 6 - 出的 ArcGIS 控件,或者说可视化控件,用来辅助应用程序开发(下文将针对控件进行更加 详细的介绍)。  MapControl  PageLayoutControl  SceneControl  GlobeControl  ToolbarControl  TOCControl  ReaderControl  ToolbarControl 中所用到的 commands(命令)、tools(工具)和 menus(菜单) 1.3.2 ArcGIS Engine Runtime ArcGIS Engine 的最后一部分是运行许可。所有用 ArcGIS Engine SDK 构建出的应用 程序都需要不同级别的 ArcGIS Engine 运行许可才能够正常运行。ArcGIS Engine Runtime 是 ArcGIS Desktop(ArcGIS 桌面版)构建的平台,如果得到 ArcGIS Engine 应用开发许 可,ArcGIS Desktop 的用户就能够执行基本的基于 Engine 的应用。ArcGIS Engine Runtime 从标准功能到企业级功能之间有许多不同的选择。 1.3.3 ArcGIS Engine 的功能 ArcGIS Engine 的功能十分强大。作为 ArcGIS Engine 开发者,您可以实现以下列出的 和其他更多的功能,这包括:  用多个图层来显示地图,例如道路、水系、边界等  地图的漫游和缩放  地图上要素的确认  地图上要素的查询和定位  根据属性值显示注记  根据航片或者卫片显示图像  绘制几何图形,例如点、线、弧、多边形  添加描述性的文字  沿着线选择或者选择矩形、某一范围内、多边形等内部的要素  选择距离在某一范围内的要素  利用 SQL 语言来寻找和选择要素  利用专题地图来渲染要素,如唯一值法、分级法和点状密度法  动态显示实时地图或者时序数据  根据地理编码来寻找位置  转换您地图的坐标系  根据几何操作来生成缓冲区、计算差值,或者进行求交、求并等运算  编辑要素形状或者旋转地图  创建并更新要素的几何形状及其属性 编辑要素(Editing Features) ArcGIS Engine 开发包让您构建出能创建、修改和删除 geodatabase 中矢量要素或者 shapefile 文件的应用程序。标准的 ArcGIS Engine Runtime 能够让编辑 shapefile 文件或者 personal geodatabase 中简单要素的程序运行。然而,要构建企业级 geodatabase 的全部 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 7 - 功能,就需要 ArcGIS Engine Runtime 中的 Geodatabase Update 选项。 空间建模和分析 通过增加 ArcGIS Engine Runtime 中的 Spatial 选项,您能够扩展 ArcGIS Engine 的功 能。这个选项(Spatial 选项)能提供一系列强劲的空间建模和分析功能。您能够创建、查 询、表达和分析基于象元的栅格数据,能够集成栅格和矢量数据进行分析,能够从已有数据 挖掘出新的信息,能够从多层数据中查询信息,能够在 ArcGIS Engine 应用程序中完美集 成基于象元的栅格数据和矢量数据。 例如,您能够:  将要素(如点、线或者面)转化成栅格图  基于距离或者要素、栅格间的关系来创建栅格缓冲区  根据点状要素生成密度图  生成等高线、坡度、可视化区域、方向和山体阴影  栅格图的分类及显示  兼容 TIFF,BIL,IMG,USGS DEM,SDTS,DTED 等标准格式及多种其他格式 数据  三维可视化等 ArcGIS Engine Runtime 中的 3D 选项让您通过使用 Scene 和 Globe 控件来有效的表 达和分析区域及全球数据。您能够从多个不同的视点查看表面;您能够查询表面,决定从某 个选中的位置看,哪些要素是可见的;您能够将栅格和矢量数据贴在表面以构建真实的透视 影像。 例如,您能够:  显示 Scene 和 Globe 文档  展示交互性的透视图,包括漫游、缩放、旋转、倾斜、模拟飞行以便于表达和分 析  显示真实世界的表面要素,例如楼房  展示视域和可见范围分析、场景高度内插、剖面分析和最短距离分析 2 ArcGIS 控件介绍 在 ArcGIS Engine 的二次开发中,ArcGIS 控件给我们提供了具体的开发环境和方法。 在 ArcGIS Engine 中共有 7 个控件,另外在部署过程中还有一个 LicenceControl。下面将首 先介绍 ArcGIS 控件,再详细介绍实习中可能用到的 MapControl,TOCControl 以及 ToolbarControl。 2.1 ArcGIS 控件简介 ArcGIS 的控件是高度集成化的,首先能够让开发者构建和扩展 ArcGIS 的功能,其次 能够提供图形用户界面(graphical user interface,GUI)。 下列展示出的每一个 ArcGIS 控件都可以被作为 ActiveX 控件,.NET 控件或者可视化 的 JavaBean:  MapControl——类似于“数据”  PageLayoutControl Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 8 -  ToolbarControl  TOCControl(Tablet of Contents Control)  SceneControl  GlobeControl  ReaderControl 使用 ArcGIS 控件,可以用两种方式来构建应用程序,首先,ArcGIS 控件可以被嵌入 到已有的应用程序中,将地图相关的功能作为辅助添加进去,或者其次,ArcGIS 控件可以 用来创建一个独立的应用程序。不管使用哪种方式,一个独立的 ArcGIS 控件能够被嵌入到 已有程序中或者 TOCControl 和 ToolbarControl 能够和其他 ArcGIS 控件联合使用,提供应 用程序的部分框架。 对于所有的 ArcGIS 控件来说,有一些共同的主题、概念和应用方法等,在有效的使用 这些控件来构建应用程序之前,有必要先有一定的理解。 2.1.1 嵌入式控件(Embeddable Components) 每个 ArcGIS 控件都是一个可嵌入的控件,能被放置到提供可视化编程环境的窗体或者 对话框内。被放置之后,这些 ArcGIS 控件能够连同别的嵌入式控件(例如命令按钮,下拉 列表框等)一样重新定义尺寸和位置以构建应用程序中的用户界面。 2.1.2 属性页(Property Pages) 当每一个 ArcGIS 控件被放置到窗体或者对话框中之后,鼠标右键点击控件,从弹出菜 单中选择“Properties”(属性),都会分别弹出一系列的属性页。这些属性页提供了控件的 部分属性和方法,并且允许开发者不使用或使用极少的代码来完成应用开发。 2.1.3 ArcObjects 每一个 ArcGIS 控件都封装了一些粗粒度(coarse grained)的 ArcObjects 以简化用户 的开发工作,但同时也提供了访问高粒度(finer grained)ArcObjects 的方法。例如, PageLayoutControl 控件封装了 PageLayout 对象(PageLayout Object)。PageLayout 对 象包含了至少一个 MapFrame 元素,其中有一个包含有多层矢量图、要素或者通常所说的 Layer 对象的 Map 对象。每一个 ArcGIS 控件提供了封装在 ArcObjects 中最频繁使用的属 性和方法的访问方法。例如,MapControl 中的 SpatialReference(空间参考)属性项,提 供了设置地图对象中空间参考属性的方法。每一个 ArcGIS 控件同时也有一些实现简单任务 的方法。例如,MapControl 有 AddShapeFile(用来添加 ShapeFile 文件)方法。ArcGIS 控件是典型应用开发的起点,不仅因为它们提供用户界面,同时也提供对象模型的直接方法。 2.1.4 事件(Events) 每一个 ArcGIS 控件都能相应终端用户的键盘和鼠标操作。其他的事件用于相应控件内 部的操作。例如,当一个地图文件被载入到 MapControl 中时,会触发 OnMapReplaced 事 件,或者说当一个对象被拖拽到 MapControl 上时,会触发 OnOleDrop 事件。 2.1.5 伙伴控件(Buddy Controls) ToolbarControl 和 TOCControl 需要和其他“伙伴控件”协同工作。通常说来,“伙伴 控件”指的是 MapControl,PageLayoutControl,ReaderControl,SceneControl 或者 GlobeControl。“伙伴控件”可以在设计时通过控件的属性页来设置(在支持属性页的编译 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 9 - 环境中设置)或者在程序中用 SetBuddyControl 方法来设置。 2.1.6 控件命令(Control Commands) ArcGIS Engine 提供了与 ArcGIS 控件一起工作的一系列命令(commands),工具 (tools)和菜单(menus)。例如,MapControl 和 PageLayoutControl 可以使用地图浏览, 要素选择和图形元素命令等。类似的,也有许多可供 SceneControl,GlobeControl 和 ReaderControl 使用。对于使用独立控件的程序来说,在程序中新建一个命令的实例,并将 这个实例通过 OnCreate 事件传递给控件就可以直接使用。对于连同“伙伴控件”一起使用 ToolbarControl 的应用程序来说,这些命令可以被直接添加到 ToolbarControl 中,既可以在 设计时通过属性页加入,也可以在程序运行过程中书写代码加入,如果在运行过程中, ToolbarControl 处于客户定制状态,还可以由终端用户添加。 开发者可以使用 ArcGIS Engine 创建自己的命令、工具和菜单来扩展 ArcGIS 控件。 HookHelper,GlobeHookHelper 和 SceneHookHelper 对象能够用来简化开发。具体的开 发方法将在第五章详细列出。 2.1.7 地图组织(Map Authoring) ArcGIS Desktop 应用程序能够创建预定义好的地图文件,之后载入到 ArcGIS 控件中 以快速获得高质量的地图。例如, ArcMap 能 创 建 可 被 载 入 到 MapControl 和 PageLayoutControl 中的地图文件。预定义地图文件能够在组织地图数据和地图符号方面节 省大量的时间。当地图文件被载入到 ArcGIS 控件中之后,在需要改变地图外观的时候,对 象模型仍然提供了通过程序来访问图层、元素和符号的方法。 下表小结了能够被载入到 ArcGIS 控件中的文件格式: 表 1 ArcGIS 控件对应的文件格式 *ArcReaderControl 只有选择 ArcGIS Publisher 扩展之后才能获得。然而,这里将其列出来 是因为与 ReaderControl 相似。 **ArcGIS控件还不提供直接载入图层文件(*.lyr)的方法。然而,它们可以通过MapDocument 对象间接载入。 2.2 重要控件简介 本次实习可能用到 MapControl,PageLayoutControl,TOCControl 和 ToolbarControl, 下面分别介绍这四种控件。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 10 - 2.2.1 MapControl 和 PageLayoutControl MapControl 和 PageLayoutControl 分别对应 ArcMap Desktop 应用中的“数据”和“发布” 视图。MapControl 中封装了 Map 对象,PageLayoutControl 中封装了 PageLayout 对象。 ArcMap 应用程序中组织的地图文件能够直接载入到 MapControl 和 PageLayoutControl 中, 以省去程序配置地图的时间。 地图文件能够在设计时通过 MapControl 和 PageLayoutControl 的属性页(在支持属性 页的开发环境中)设置,控件可以被设置为“链接”(link)或者“包含”(contain)地图文件。 当选择“链接”时,控件将在生成的时候将地图载入并显示出地图文件的最新更新;而选择“包 含”时,控件将会将地图文件中的内容复制到控件中,并且不再显示至此之后发生的文件更 新。同时,您也可以选择使用 LoadMxFile 方法在程序运行过程中载入地图文件(这种方法在 之后的章节中会有详细介绍)。下面详细介绍 MapControl 和 PageLayoutControl 的属性页。 1. MapControl 在 MapControl 控件上点击鼠标右键,选择属性,打开 MapControl 的属性页。 属性页中包含 General、Map、Color、picture 四个选项卡。 General 选择卡: Border Style: 用 于 设 置 MapControl 控件边界的样式 Appearance: 用 于 设 置 MapControl 控件的表现方式。 Mouse Pointer:用于设置鼠标在 MapControl 上的样式。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 11 - Enabled:设置控件是否可用,这 与属性表中的 Enabled 属性在功 能上是相同的。 Enable OLE Drop Event:设置控 件是否响应拖拽事件,例如:直接 将地图拖入 MapControl Preview in Design Mode: 设置是 否在控件设计模式下显示地图。 Arrow Key Intercept:设置是否容 许控件响应键盘 Tooltip Style:设置地图 Tooltip 的 样式(ToolTip 是地图上的一种动 态标注。) Map Document : 用 于 载 入 ArcMap 产生的 MXD 文件,如果 您的文件时 MXD 类型的,可以选 择这种方式载入地图,或代码在程 序中载入。关于后一种方法会在 《通过代码载入图层》小节中加以 介绍。 选择地图载入的方式,有两种方式 载入地图,第一种是将地图数据载 入到 MapControl 中,这种方式下, 地图数据在生成程序时被载入到 内存中,之后所有对地图的操作, 在没有保存的前提下对原始的地 图文件没有影响。 第二种方式,通过连接方式载入地 图,表示对于地图的操作会影响到 原始数据。在 MapControl 中只是 保持着与地图数据的链接。 Map 选项卡 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 12 - Scale:显示地图比例尺 Reference Scale:地图参考比例尺 Rotation:设置地图的旋转角度 Units:设置单位 Spatial Reference:设置或更改地图的 空间参考。 Initial Map:初始化地图 从左到右按钮的功能依此是: 加载图层(图层可以是单图层文件,可 以 使 GoeDatabase , 也 可 以 是 Shapefile) 向上移动图层、向下移动图层、删除图 层、查看图层属性信息。 Color 选项卡主要对地图颜色进行相关的设置,但通常关于地图的配色我们是通过 代码来完成的,这个选项卡很少涉及。 Picture 选项卡主要是对控件中的相关图片资源进行管理,例如鼠标样式等。 2. PageLayoutControl Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 13 - 对于 PageLayoutControl 控件的属性页而言,唯一与 MapControl 不同的是他存在 page 选项卡,该选项卡提供了页面大小,页面宽度和高度等修改的窗口。 MapControl 和 PageLayoutControl 不仅可以读地图文件,同时也能写地图文件 (*.mxd)。两个控件都实现了IMxdContents接口,使得MapDocument对象能将MapControl 和 PageLayoutControl 能够将其中的内容写入地图文件。 辅助方法(Helper Methods),例如 MapControl 中的 TrackRectangle(鼠标绘制矩形), TrackPolygon(鼠标绘制多边形),TrackLine(鼠标绘制多段线)和 TrackCircle(绘制弧 形)方法能够在视口中绘制出可擦出的图形。VisibleRegion 属性能够改变 MapControl 中显 示区域的形状。辅助方法,例如 PageLayoutControl 中 的 FindElementByName 和 LocateFrontElement 方法能帮助开发者组织元素,同时 Printer 和 PrinterPageCount 属性 能够协同 PrintPageLayout 方法完成打印输出任务。 2.2.2 TOCControl TOCControl 需要与一个“伙伴控件”一同工作。“伙伴控件”可以是一个 MapControl, PageLayoutControl,ReaderControl,SceneControl 或者 GlobeControl。“伙伴控件”能够 在设计的时候通过 TOCControl 的属性页设置(在支持属性页的编译环境中),或者在程序 运行中通过 SetBuddyControl 方法来设置。对每个 TOCControl,“伙伴控件”都实现了 ITOCBuddy 接口。TOCControl 利用“伙伴控件”来显示交互性的树结构目录,包括“伙伴控件” 的地图、图层、符号等内容,并且保持树结构的内容与“伙伴控件”的内容一致。例如,如果 TOCControl 以 MapControl 作为其“伙伴”,则当一个图层从 MapControl 中移除的时候,这 个图层也会同时从 TOCControl 中移除。同样的,如果终端用户通过交互式的 TOCControl 设置,取消了某个图层的可见性,则 MapControl 中的相应图层也会不可见。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 14 - 与 MapControl 不同的是,TOCControl 的属性表中包含 Buddy Control,如果你已经添 加了 MapControl,那么在下拉列表中你就会看到它,选择他就可以讲 TOCControl 与 MapControl 绑定。 2.2.3 ToolbarControl ToolbarControl 需要与一个“伙伴控件”一同工作。“伙伴控件”可以是一个 MapControl, PageLayoutControl,ReaderControl,SceneControl 或者 GlobeControl。“伙伴控件”能够 在设计的时候通过 ToolbarControl 的属性页设置(在支持属性页的编译环境中),或者在程 序运行中通过 SetBuddyControl 方法来设置。ToolbarControl 包含了与“伙伴控件”的显示相 关的一系列的命令(commands),工具(tools),工具控件(tool controls)和菜单(menus)。 对每个 ToolbarControl,“伙伴控件”都实现了 IToolbarBuddy 接口。这个接口是用来设 置“伙伴控件”的 CurrentTool 属性。例如,一个 ToolbarControl 中包含有一个“PageZoomIn” (页面放大)工具,并且将 PageLayoutControl 设置为“伙伴”,则当终端用户单击 ToolbarControl 上的“PageZoomIn”时,“PageZoomIn”将会成为 PageLayoutControl 的当前 工具。“PageZoomIn”工具将查询 ToolbarControl 以访问其“伙伴控件”(PageLayoutControl) 并且作用于 PageLayout(页面视图),然后它将提供给终端用户显示和使用鼠标拉框的方 法以改变 PageLayout 的显示范围。 ToolbarControl 实现了 ArcGIS 中的所有功能,用户可以在不编写一行代码的情况下, 轻松构架出一个功能庞大的 GIS 软件,只要是 ArcGIS 中含有的功能,你都会在 ToolbarControl 中找到。但是这些功能都是事先封装好的,如果你想对这些功能进行进一步 的扩展,难度很大。所以不要以为有了 ToolbarControl 就可以摆脱学 GIS 二次开发的过程。 让我们来看看我们是如何使用 ToolbarControl 的。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 15 - 在 ToolbarControl 的属性页中有一个 Items 的选项卡,通过选项卡中的 Add 按钮可以添 加相应的功能按钮。点击 Add,会出现以下对话框。 该对话框包含了很多已经封装好的工具,包括复杂的空间分析功能。双击其中的功能 或拖拽,就可以讲该功能添加到 ToolBarControl 中。需要删除时,在 Items 中的按钮列表中 将功能拖出即可,按钮列表如下图所示: Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 16 - 3 ArcGIS Engine 二次开发入门 3.1 ArcGIS Engine 开发起步——第一个简单的地图显示程序 这个例子将引导您创建第一个简单的地图显示程序,并添加基本的缩放和漫游功能。 如果您之前没有接触过 ArcGIS Engine 的开发,那么这个例子是您迈入 ArcGIS Engine 二 次开发大门的极好例子,如果您之前没有接触过 Visual Basic.NET,也无需担心,这个例子 将从零开始引导您一步一步完成任务。 3.1.1 创建一个新的工程 首先打开 Microsoft Visual Studio 2005,点击菜单栏中的“文件”—>“新建”—>“项目”, 在弹出的对话框中选择新建一个 Visual Basic 的 Windows 应用程序,之后更改项目名称为 “MapView”,更改文件的路径为个人实习文件夹,点击“确定”即可。 图 23 新建项目对话框 3.1.2 添加控件及引用 点击编译器最左侧的“工具箱”,在弹出的选择项中找到“ArcGIS Windows Forms”项, 单击其中的 MapControl,之后在 Form1 的空白处单击鼠标左键不放并拖拽鼠标,直到调整 MapControl 到合适的大小再松开鼠标(您也可以直接在工具箱中双击 MapControl,该控件 则会自动加入到 Form1 中)。用同样的方法,再将 LicenseControl 添加到 Form1 中。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 17 - 图 24 工具箱 如果您在工具箱中找不到 MapControl,则请依次尝试以下两种解决方案。首先单击工 具栏,待工具箱弹出之后,在工具箱的任意位置上单击鼠标右键,从弹出菜单中选择“重置 工具箱”。如果这一步操作之后仍然无法看到 MapControl,则请滑动工具栏右侧的滚动条至 最底部,找到“常规”选项卡,然后在“常规”选项卡上单击鼠标右键,在弹出菜单中单击“选择 项(I)…”,在弹出的对话框中找到“AxLicenseControl”和“AxMapControl”,将这两项前的 复选框打上勾,最后点击确定即可(如果在“.NET Framework 组件”这个面板中找不到这两 项,则选择“COM 组件”面板,在“ESRI LicenseControl”和“ESRI MapControl”前面打勾)。 图 25 重置工具箱 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 18 - 图 26 选择项… 图 27 选择工具箱项 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 19 - 图 28 选择工具箱项 添加好 MapControl 和 LicenseControl 之后,调整 Form1 和 MapControl 的位置与大小, 如下图所示: 图 29 窗体布局 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 20 - 3.1.3 添加地图 在 MapControl 上单击鼠标右键,选择“属性”,则会弹出 MapControl 的属性设置面板, 在之前也介绍过,通过这个面板可以完成许多简单的工作。 如图所示,点击“Map”面板,之后点击 按钮,在弹出的对话框中选择下图所示的路 径(注:笔者的 ArcGIS 安装在 D 盘,若您的 ArcGIS 装在别的盘符,请做相应修改),再 在此路径下选择“States”,点击“Open”。之后在 MapControl 的属性页上点击“确定”即可。 图 30 文件添加路径 至此,我们已经完成了一个最简单的地图显示程序,下面一起来看一下成果吧。点击 “启动调试”按钮(或者在“调试”菜单下选择相应命令,或者按键盘的 F5 键),可以得 到如下的运行结果。 图 31 “启动调试”按钮 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 21 - 图 32 初次运行结果 3.1.4 添加基本的代码 我们没有书写任何代码,就得到了一个最简单的地图显示程序。但这个程序还不能与 用户交互,下一步我们需要添加一些代码,让程序能响应用户的鼠标,完成放大和全图显示 的功能。 图 33 MapControl 控件支持的所有方法 双击 MapControl 控件,可以进入代码编辑界面。从窗口上方的下拉列表框中,我们能 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 22 - 够看到 MapControl 能够响应的所有事件(关于每个事件的详细使用方法等请参见帮助系统, 第六章对帮助系统有更加详细的介绍)。双击 MapControl 进入代码编辑界面的时候,默认 的是“OnMouseDown”事件,下一步就需要在这个事件中添加响应鼠标的相关代码。 请您在 Private Sub AxMapControl1_OnMouseDown 函数中添加如下代码: If e.button = 1 Then AxMapControl1.Extent = AxMapControl1.TrackRectangle ElseIf e.button = 2 Then AxMapControl1.Extent = AxMapControl1.FullExtent End If 再次运行程序,鼠标左键在地图上拉框可以实现地图的放大功能,而右键单击地图则 会还原地图的全图显示。 图 34 任意比例尺放大功能 如果将代码替换如下,则能实现左键放大,右键漫游的功能。 If e.button = 1 Then AxMapControl1.Extent = AxMapControl1.TrackRectangle ElseIf e.button = 2 Then AxMapControl1.Pan() End If 3.1.5 代码解释 下面我们依次来看看这些代码都代表什么意思。首先看来第一段: If e.button = 1 Then AxMapControl1.Extent = AxMapControl1.TrackRectangle ElseIf e.button = 2 Then AxMapControl1.Extent = AxMapControl1.FullExtent End If Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 23 - 这个代码是一个 If Else 条件语句,关于“e”的详细定义及其中包含的各参数,请参考帮 助中与“IMapControlEvents2, OnMouseDownEventHandler delegate”关键字相关的内容。 可以根据 e 中包含的“button”值来判断鼠标的单击操作是来自何处,若 button 值为 1, 则为鼠标左键,2 代表鼠标右键,4 代表鼠标中键。当判断得到是鼠标左键单击时,执行 “AxMapControl1.Extent = AxMapControl1.TrackRectangle”这条语句,其中,等号右侧是调用了 “TrackRectangle”方法,这个方法是在地图上拖拽出一个矩形,之后将这个矩形赋值给当前 地图的显示区域(Extent),这样就实现了地图的放大功能。类似的,若鼠标右键单击,则 将全图范围赋值给当前的显示范围,实现了地图的全图显示功能。 第二段代码与第一段结构一样,只是在右键的相应事件上略有不同,这是调用了“Pan” 方法,实现了地图的漫游功能。 3.1.6 小结 通过这个例子,我们制作出了一个最简单的地图浏览程序 MapView,并能响应一些基 本的鼠标操作。在 MapControl 的属性页中,其实还有许多内容您可以尝试,例如在“General” 面板中可以直接加入地图文件(*.mxd 或者*.mxt),您也可以利用刚才的方式一次性多加入 一些图层而不仅仅加入“States”一个,同时可以更改各图层的叠放次序,也可以在“Data” 面板中设置地图的旋转角度(Rotation)等,您还可以设置 MapControl 的显示方式,是否支 持地图的预览功能,边框样式等等。您可以做一些尝试,看看能得到哪些有趣的结果,这些 尝试对您今后熟悉 ArcGIS Engine 的开发是有一定帮助的。如果需要重置 MapControl,只需 要点击“Data”面板中的“Reset”按钮。当您完成了这个例子,并做了一些积极的尝试之 后,您就可以接着学习下一个小节的内容了。 3.2 属性查询 查询是 GIS 中非常重要的一个功能,下面将分别介绍属性查询和空间查询的制作方法。 3.2.1 添加控件 如果上一小节的工程已经关闭,则将其打开,如果您之后又在 MapControl 中添加了一 些别的数据,请将其删除,只保留一个“states”图层,请务必注意这一步,这直接关系到您 下面的工作能否顺利进行。用之前讲过的方式,在窗体中添加一个 Label 和一个 TextBox。 将 Label 的“Text”属性修改为“StateName”,结果如下: 图 35 Label 控件和 TextBox 控件 3.2.2 添加引用和代码 首先添加引用。点击菜单栏上的“项目”—>“添加引用”,在弹出的对话框中同时选择 “ESRI.ArcGIS.Carto”和“ESRI.ArcGIS.Geodatabase”(选择的时候按下 Ctrl 键以同时选择多 个),点击确定。 之后双击 TextBox1 控件,进入代码编辑界面。在代码编辑区域的最上方输入以下内容: Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 24 - Imports ESRI.ArcGIS.Carto Imports ESRI.ArcGIS.Geodatabase 如下图所示: 图 36 引用添加位置 图 37 添加引用对话框 之后在 TextBox1 的事件中选择 KeyPress,在 KeyPress 事件中添加以下代码: 图 38 KeyPress 方法 If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Return) Then Dim pFeatureLayer As IFeatureLayer Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 25 - Dim pCursor As IFeatureCursor Dim pFilter As IQueryFilter Dim pFeature As IFeature pFeatureLayer = Me.AxMapControl1.Map.Layer(0) If Not pFeatureLayer.Name = "states" Then Exit Sub Me.AxMapControl1.Map.ClearSelection() pFilter = New QueryFilter pFilter.WhereClause = "STATE_NAME = '" & TextBox1.Text & "'" pCursor = pFeatureLayer.Search(pFilter, True) pFeature = pCursor.NextFeature If pFeature Is Nothing Then Me.AxMapControl1.Refresh() MessageBox.Show("没有找到名为" & TextBox1.Text & "的州", "Infomation", MessageBoxButtons.OK) Exit Sub Else Me.AxMapControl1.Map.SelectFeature(pFeatureLayer, pFeature) Me.AxMapControl1.Extent = pFeature.Shape.Envelope End If End If 运行程序,分别向编辑框中输入“Texas”和“RS”,键入回车,如下图所示: 图 39 Texas 州查询结果 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 26 - 图 40 RS 查询结果 3.2.3 代码解释 If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Return) Then 上述代码是一个判断语句,即当用户输入回车的时候,开始进行查询。 下面两行代码是定义查询的范围,默认为上一小节中添加的图层“states”,如果找不 到这个图层则自动退出。 pFeatureLayer = Me.AxMapControl1.Map.Layer(0) If Not pFeatureLayer.Name = "states" Then Exit Sub Me.AxMapControl1.Map.ClearSelection()是为了将上一次的查询结果清除。 pFilter = New QueryFilter pFilter.WhereClause = "STATE_NAME = '" & TextBox1.Text & "'" pCursor = pFeatureLayer.Search(pFilter, True) pFeature = pCursor.NextFeature 这一部分是生成一个新的查询器,选择条件(WhereClause)就是检索是否有与用户 输入相符的州,并将结果从查询得到的 pCursor 中读取出来。 If pFeature Is Nothing Then Me.AxMapControl1.Refresh() MessageBox.Show("没有找到名为" & TextBox1.Text & "的州", "Infomation", MessageBoxButtons.OK) Exit Sub Else Me.AxMapControl1.Map.SelectFeature(pFeatureLayer, pFeature) Me.AxMapControl1.Extent = pFeature.Shape.Envelope End If 这一部分是一个判断语句,若查询得到的结果为空,则刷新地图,弹出对话框通知用户 没有查询到结果,并退出程序。如果查询得到的结果不为空,则将这个结果加入地图的选择 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 27 - 集,并将地图的显示范围定为查询结果的外轮廓,这样得到的州将高亮显示同时居中放大到 屏幕中心。 3.2.4 小结 这一部分中,我们接触到了基本的属性查询。但是在这个例子中,我们不能实现对属 性表中任意属性字段的查询(在这个程序中,我们只能查询州名——STATE_NAME,而不 能对别的字段进行查询),而且这个查询不支持模糊查询。为了使查询变的更加丰富,更加 人性化,请您参考 IQueryFilter 接口中 WhereClause 属性的设置方法,拓展 WhereClause 可以得到许多有趣的结果。在书写代码的过程中,对任何有疑问的地方,或者您想要拓展的 位置,都可以在帮助系统中查询相关的接口和属性,查看最原始的定义,帮助系统中的解释 和定义对于您熟悉 ArcObjects,熟悉 ArcGIS Engine 的二次开发以及后续的工作都是十分 重要的,请一定不要忽视这个环节。如果您已经尝试了一些变化,或者对本小节的内容比较 熟悉了,则可以进入下一小节的学习。 3.3 空间查询 上一小节我们已经学习了如何进行属性查询,在这一小节中,我们将继续学习 GIS 中 的另一种查询方式——空间查询。 3.3.1 添加控件 如果上一小节的工程已经关闭,则将其打开,如果您之后又在 MapControl 中添加了一 些别的数据,请将其删除,只保留一个“states”图层,请务必注意这一步,这直接关系到您 下面的工作能否顺利进行。我们接着上一小节的内容继续完善。在窗体中添加一个 Button, 将其 Text 属性修改为“点查询”。 图 41 添加“点查询”按钮 3.3.2 添加引用和代码 利用上一小节讲的方式,添加引用“ESRI.ArcGIS.Geometry”,并在类中添加一个全局 变量 nMouseFlag,如下图所示: Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 28 - 图 42 添加引用“ESRI.ArcGIS.Geometry” 之后在类中添加一个公共函数,用来根据屏幕像素计算实际的地理距离。 Public Function ConvertPixelsToMapUnits(ByVal pActiveView As IActiveView, ByVal pixelUnits As Double) As Double Dim realWorldDisplayExtent As Double Dim pixelExtent As Integer Dim sizeOfOnePixel As Double pixelExtent = pActiveView.ScreenDisplay.DisplayTransformation.DeviceFrame.Right - pActiveView.ScreenDisplay.DisplayTransformation.DeviceFrame.Left realWorldDisplayExtent = pActiveView.ScreenDisplay.DisplayTransformation.VisibleBounds.Width sizeOfOnePixel = realWorldDisplayExtent / pixelExtent ConvertPixelsToMapUnits = pixelUnits * sizeOfOnePixel End Function 此后,双击 Button1,进入 Button 的 Click 事件,向其中添加如下代码: nMouseFlag = 1 Me.AxMapControl1.MousePointer = ESRI.ArcGIS.Controls.esriControlsMousePointer.esriPointerCrosshair (注:上两行代码应该书写在一行,由于空间有限,这里写为两行) 最后将 MapControl 控件的 OnMouseDown 事件中已有的代码清除,替换为以下代码: If nMouseFlag = 1 Then Dim pFeatureLayer As IFeatureLayer Dim pFeatureClass As IFeatureClass Dim pSpatialFilter As ISpatialFilter Dim pFilter As IQueryFilter Dim pActiveView As IActiveView Dim pPoint As IPoint Dim pBuffer As IGeometry Dim length As Double Dim n As Long Dim pTopo As ITopologicalOperator Dim pCursor As IFeatureCursor Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 29 - Dim pFeature As IFeature pFeatureLayer = Me.AxMapControl1.Map.Layer(0) If Not pFeatureLayer.Name = "states" Then Exit Sub pFeatureClass = pFeatureLayer.FeatureClass If pFeatureClass Is Nothing Then Exit Sub pActiveView = Me.AxMapControl1.Map pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y) length = ConvertPixelsToMapUnits(pActiveView, 2) pTopo = pPoint pBuffer = pTopo.Buffer(length) pSpatialFilter = New SpatialFilter pSpatialFilter.Geometry = pBuffer Select Case pFeatureClass.ShapeType Case esriGeometryType.esriGeometryPoint pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains Case esriGeometryType.esriGeometryPolyline pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses Case esriGeometryType.esriGeometryPolygon pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects End Select pSpatialFilter.GeometryField = pFeatureClass.ShapeFieldName pFilter = pSpatialFilter pCursor = pFeatureLayer.Search(pFilter, False) pFeature = pCursor.NextFeature If pFeature Is Nothing Then Exit Sub Me.AxMapControl1.Map.ClearSelection() Me.AxMapControl1.Map.SelectFeature(pFeatureLayer, pFeature) Me.AxMapControl1.Refresh() n = pFeature.Fields.FindField("STATE_NAME") MessageBox.Show(pFeature.Value(n), "StateName", MessageBoxButtons.OK) End If 运行程序,结果如下图所示: Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 30 - 图 43 空间查询运行结果 3.3.3 代码解释 距离转换函数请您自行参看帮助系统中对相关接口的具体定义和解释。 Button1 的 Click 事件中是将 nMouseFlag 设置为 1,并将鼠标在 MapControl 上的形状 改变为十字丝状。 pActiveView = Me.AxMapControl1.Map pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y) 上述代码是在 MapControl 的 OnMouseDown 事件中,当您单击鼠标左键的时候,将 屏幕上的点转换成地图上的点(关键在于坐标值的转换),方便后续操作。 length = ConvertPixelsToMapUnits(pActiveView, 2) pTopo = pPoint pBuffer = pTopo.Buffer(length) 这一部分是将 2 个像素的距离转换成实际的地理距离,并以这个距离为半径,上一步 生成的点为中心,生成一个缓冲区。 pSpatialFilter = New SpatialFilter pSpatialFilter.Geometry = pBuffer Select Case pFeatureClass.ShapeType Case esriGeometryType.esriGeometryPoint pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains Case esriGeometryType.esriGeometryPolyline pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses Case esriGeometryType.esriGeometryPolygon pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects End Select pSpatialFilter.GeometryField = pFeatureClass.ShapeFieldName pFilter = pSpatialFilter 上述代码是设置 pSpatialFilter 的各项参数,供后续查询,包括空间查询的几何形状(之 前生成的缓冲区),空间查询的方式(相交,包含等)以及 Shape 字段。 n = pFeature.Fields.FindField("STATE_NAME") Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 31 - MessageBox.Show(pFeature.Value(n), "StateName", MessageBoxButtons.OK) 这两句代码是找出“STATE_NAME”所在的列数,并将其显示出来。 3.3.4 进一步完善空间查询 在本节中我们完成更多的空间查询功能,其中有点查询、线查询、矩形查询、圆查询 新建一个 VB.Net 工程,向工程中添加控件,如下图所示: 其中包括 MapControl,4 个 Button,一个 TextBox 通过在控件属性中添加地图的方法,向 Mapcontrol 中添加例子数据。(例子数据是位于 World 文件夹下的 Continents.lyr)如下图所示: 添加完毕后我们向工程中添加一个公共的代码模块。在下图所示的菜单中选择添加模块菜单 项。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 32 - 在弹出的菜单中选择模块完成添加。 在模块中添加公共代码。(模块中的代码可以同时被多个类进行使用,属于公共模块) Imports ESRI.ArcGIS.Carto Imports ESRI.ArcGIS.Geometry Imports ESRI.ArcGIS.Geodatabase Module Module1 Public Function ConvertPixelsToMapUnits(ByVal pActiveView As IActiveView, ByVal pixelUnits As Double) As Double Dim realWorldDisplayExtent As Double Dim pixelExtent As Integer Dim sizeOfOnePixel As Double pixelExtent = pActiveView.ScreenDisplay.DisplayTransformation.DeviceFrame.right - pActiveView.ScreenDisplay.DisplayTransformation.DeviceFrame.left realWorldDisplayExtent = pActiveView.ScreenDisplay.DisplayTransformation.VisibleBounds.Width sizeOfOnePixel = realWorldDisplayExtent / pixelExtent ConvertPixelsToMapUnits = pixelUnits * sizeOfOnePixel End Function Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 33 - Public Sub SelectRectangle(ByVal pGeometry As IGeometry) Dim pFeatureLayer As IFeatureLayer Dim pFeatureClass As IFeatureClass Dim pSpatialFilter As ISpatialFilter Dim pFilter As IQueryFilter Dim pActiveView As IActiveView Dim pCursor As IFeatureCursor Dim pFeature As IFeature form1.AxMapControl1.Map.ClearSelection() Try pFeatureLayer = form1.AxMapControl1.Map.Layer(0) pFeatureClass = pFeatureLayer.FeatureClass If pFeatureClass Is Nothing Then Exit Sub pActiveView = form1.AxMapControl1.Map pSpatialFilter = New SpatialFilter pSpatialFilter.Geometry = pGeometry Select Case pFeatureClass.ShapeType Case esriGeometryType.esriGeometryPoint pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains Case esriGeometryType.esriGeometryPolyline pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses Case esriGeometryType.esriGeometryPolygon pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects End Select pSpatialFilter.GeometryField = pFeatureClass.ShapeFieldName pFilter = pSpatialFilter pCursor = pFeatureLayer.Search(pFilter, False) pFeature = pCursor.NextFeature Dim str As String = "您选中的国家有:" form1.AxMapControl1.Map.ClearSelection() '获取查询得到的要素总数 While Not pFeature Is Nothing Dim n As Integer = pFeature.Fields.FindField("CONTINENT") form1.AxMapControl1.Map.SelectFeature(pFeatureLayer, pFeature) str = str & pFeature.Value(n) & "; " pFeature = pCursor.NextFeature End While form1.TextBox1.Text = str form1.AxMapControl1.MousePointer = ESRI.ArcGIS.Controls.esriControlsMousePointer.esriPointerArrow Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 34 - form1.AxMapControl1.Refresh() Catch ex As Exception MessageBox.Show(Err.Description, "Wrong", MessageBoxButtons.AbortRetryIgnore) End Try form1.AxMapControl1.Refresh() End Sub End Module 在Form1的代码界面添加如下引用和全局变量 在设计页面双击点查询按钮,进入点击按钮响应事件填写如下代码。 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click '点查询 nMouseFlag = 1 Me.AxMapControl1.MousePointer = ESRI.ArcGIS.Controls.esriControlsMousePointer.esriPointerCrosshair End Sub 相应的线查询、矩形查询、圆查询添加同样的代码,但nMouseFlag得值要有所改变。 线查询:nMouseFlag=2 矩形查询:nMouseFlag=3 圆查询:nMouseFlag=4 为MapControl控件添加OnMouseDown事件,填入以下代码 If nMouseFlag = 1 Then Dim pActiveView As IActiveView Dim pPoint As IPoint Dim pBuffer As IGeometry Dim length As Double Dim pTopo As ITopologicalOperator pActiveView = Me.AxMapControl1.Map pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y) length = ConvertPixelsToMapUnits(pActiveView, 2) pTopo = pPoint pBuffer = pTopo.Buffer(length) SelectRectangle(pBuffer) End If If nMouseFlag = 2 Then SelectRectangle(Me.AxMapControl1.TrackLine) End If If nMouseFlag = 3 Then SelectRectangle(Me.AxMapControl1.TrackRectangle) Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 35 - End If If nMouseFlag = 4 Then SelectRectangle(Me.AxMapControl1.TrackCircle) End If 点击运行,运行效果如下图所示: 仔细研读代码,您会发现,在这部分中我们并没有用到什么新的知识,只是在结构上做了 调整,应为空间查询都是需要使用一个IGeometry对象进行空间求交进行查询的。所以我 们将公共的代码放在公共的模块中进行调用。有心的同学可能发现,我们为了判断用户在 MapControl上的操作,我们引入了一个全局变量nMouseFlag,程序中多一个全局变量, 对程序的结构的封闭性就有所破坏,能不能去掉这个全局变量而是Mapcontrol自主判断是 哪个功能进行操作呢?答案是肯定的,我们可以使用BaseCommand和BaseTool来完成这 个工作,详细的用法在3.4和3.5小节将会介绍。 3.3.5 小结 在这一小节中,我们学习了如何进行简单的空间查询。空间查询不仅包括点查询,还 包括线查询,矩形查询,多边形查询等(为了实现这些功能,可以参考 MapControl 中的 TrackRectangle 等方法)。对于这一小节的代码,强烈建议您参看帮助系统中对相关接口的 解释和定义,以进一步熟悉接口的使用,这对后面的学习以及掌握 ArcGIS Engine 二次开 发是极有好处的。如果您对这一部分比较熟悉了,可以进入下一小节。在第四章中,我们介 绍了控件命令(Control Commands),并提到 ArcGIS Engine 允许用户自定义开发一些控 件命令,在下两小节中,我们将具体学习如何开发。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 36 - 3.4 BaseCommand 开发实例 在这一小节中,我们将学习 BaseCommand 的开发步骤。BaseCommand 的功能与 Button 的功能类似,是当鼠标点击按钮的时候,MapControl 控件会对其中的命令做出相应 而无需额外的操作。在这一小节中,我们将制作一个“定比例尺放大”的按钮,当鼠标单击按 钮时,地图将居中放大一倍。 3.4.1 添加控件 如果上一小节的程序已经关闭,则重新打开,同时保证 MapControl 控件中加载了至少 一个图层。在主窗体(frmMain)中添加一个 Button,将其 Text 属性更改为“居中放大”。 3.4.2 添加 BaseCommand 点击菜单栏上的“项目”—>“添加类”,弹出以下对话框。 图 44 添加新项对话框 如上图所示,在类别中选择 ArcGIS 项,在右侧的模板中选择“BaseCommand”项,并 在名称中将其更改为“cmdFixedZoomIn”,点击添加,出现如下对话框。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 37 - 图 45 类别选择向导 我们这个命令是用于 MapControl 控件的,所以在选择项中选择第二项,点击 OK。 3.4.3 添加代码 双击解决方案资源管理器中的 cmdFixedZoomIn.vb 项,进入该类的代码编写界面。首 先按照前几节介绍过的方法,加入引用“ESRI.ArcGIS.Geometry”,并在该类的最上方添加 如下代码: Imports ESRI.ArcGIS.Geometry 如上图所示,将 MyBase.m_toolTip 和 MyBase.m_name 做相关修改,分别更改为“居中 放大”和“cmdFixedZoomIn”。之后在 OnClick()函数中添加如下代码: Dim pEnvelope As IEnvelope pEnvelope = frmMain.AxMapControl1.Extent Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 38 - pEnvelope.Expand(0.5, 0.5, True) frmMain.AxMapControl1.Extent = pEnvelope 转到主窗体(frmMain),双击“居中放大”按钮,进入该按钮 Click 事件相应函数,添加 如下代码: Dim pcmdFixedZoomIn As New cmdFixedZoomIn pcmdFixedZoomIn.OnCreate(Me.AxMapControl1.Object) pcmdFixedZoomIn.OnClick() 3.4.4 运行 运行程序,点击“居中放大”时,地图会放大一倍。点查询功能依然可用,如下图: 图 46 程序运行结果 3.4.5 小结 在这一小节中,我们学习到了如何制作一个 BaseCommand。使用 BaseCommand 的好处 主要有,首先按照面向对象的思想,居中放大这个功能已经被封装在我们自己书写的类中, 若是以后需要再将这个功能移植到别的程序,或者由多个程序员共同完成一个程序时,只需 要将这个类复制到相关工程下,稍作调整即可运行;其次,我们可以发现,同样是实现放大 功能,之前我们是直接在 MapControl 控件的 OnMouseDown 事件中添加代码,而现在是具 体的写入到了每个类中。这样做可以是代码更易读,而且当需要完成许多不同的功能时,这 种方法的优势就体现出来了,因为我们不需要再单独设立一个 MouseFlag 变量来判断具体用 户点击了哪个按钮,MapControl 的 OnMouseDown 事件中也无需再添加冗长的代码,而是分 散到各类中,增强了程序的稳定性。 在新建 cmdFixedZoomIn 类的同时,我们发现还会附带生成一个 cmdFixedZoomIn.bmp 位图文件,您可以双击这个图标以做相关编辑更改工作,也可以用自己的图标来替换(注意 保持文件名一致)。这个图标的作用,是在使用 ToolbarControl 的时候,用于显示按钮图标 的。您可以尝试着在工程中加入一根 ToolbarControl,并使用 AddItem 方法添加我们写好的 这个类,看能否得到一样的结果。如果您对本小节的内容比较熟悉,也做了一些积极的尝试, 那么您可以进入下一小节的学习。在下一小节中我们将学习 BaseTool 的开发方法。 3.5 BaseTool 开发实例 经过上一小节的学习,我们了解到了如何自定义 BaseCommand 来拓展 ArcGIS 的应 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 39 - 用。在这一小节中,我们将改写之前做过的点查询功能,将这项功能独立写成一个 BaseTool。 BaseTool 与 BaseCommand 有些相似的地方,它们都是点击之后可以对 MapControl 控件 做相应的操作,但是 BaseCommand 点击之后 MapControl 会直接予以相应,不需要额外 的操作,而对于 BaseTool 来说,需要用户再用鼠标对地图做进一步交互式的操作, MapControl 控件才会予以相应。例如在第二小节中制作的拉框放大功能,需要鼠标在地图 上交互式的选取一个范围,地图才会予以相应,同样,我们这一小节要改写的点查询功能也 是如此,需要您再在地图上单击鼠标才会予以响应。下面我们开始 BaseTool 的制作。 3.5.1 打开工程 我们这里需要在上一小节的基础上继续完善,如果您已经将 MapView 关闭,请重新打 开,并保证 MapControl 中只加载了一个“states”图层,请务必注意这一步,这直接关系到您 后面的工作能否顺利进行。 3.5.2 添加 BaseTool 在菜单栏上选择“项目”——“添加类”,出现如下对话框: 图 47 添加新项对话框 在类别中选中 ArcGIS,在末班中选择 BaseTool,并将名称更改为“toolPointQuery”,点 击添加,出现如下对话框: Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 40 - 图 48 类别选择向导 我们这个工具是要用于 MapControl,故选择第二项,点击 OK。 3.5.3 添加引用和代码 双击解决方案资源管理器中的 toolPointQuery.vb,进入该类的代码编写界面。 首先添加三个引用,如下图所示: 类似的,如下图所示,对 MyBase.m_toolTip 和 MyBase.m_name 做相关修改。 再在 toolPointQuery.vb 类中的 OnMouseDown 函数中添加如下代码: Dim pFeatureLayer As IFeatureLayer Dim pFeatureClass As IFeatureClass Dim pSpatialFilter As ISpatialFilter Dim pFilter As IQueryFilter Dim pActiveView As IActiveView Dim pPoint As IPoint Dim pBuffer As IGeometry Dim length As Double Dim n As Long Dim pTopo As ITopologicalOperator Dim pCursor As IFeatureCursor Dim pFeature As IFeature Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 41 - pFeatureLayer = frmMain.AxMapControl1.Map.Layer(0) If Not pFeatureLayer.Name = "states" Then Exit Sub pFeatureClass = pFeatureLayer.FeatureClass If pFeatureClass Is Nothing Then Exit Sub pActiveView = frmMain.AxMapControl1.Map pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y) length = frmMain.ConvertPixelsToMapUnits(pActiveView, 2) pTopo = pPoint pBuffer = pTopo.Buffer(length) pSpatialFilter = New SpatialFilter pSpatialFilter.Geometry = pBuffer Select Case pFeatureClass.ShapeType Case esriGeometryType.esriGeometryPoint pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains Case esriGeometryType.esriGeometryPolyline pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses Case esriGeometryType.esriGeometryPolygon pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects End Select pSpatialFilter.GeometryField = pFeatureClass.ShapeFieldName pFilter = pSpatialFilter pCursor = pFeatureLayer.Search(pFilter, False) pFeature = pCursor.NextFeature If pFeature Is Nothing Then Exit Sub frmMain.AxMapControl1.Map.ClearSelection() frmMain.AxMapControl1.Map.SelectFeature(pFeatureLayer, pFeature) frmMain.AxMapControl1.Refresh() n = pFeature.Fields.FindField("STATE_NAME") MessageBox.Show(pFeature.Value(n), "StateName", MessageBoxButtons.OK) 再进入 frmMain 窗体中 MapControl 控件的 OnMouseDown 响应函数,将其中的内容 全部删除。 双击 frmMain 窗体上的“点查询”按钮,进入 Click 事件响应函数,将其中的代码删除, 用下列代码替代: Dim pToolPointQuery As New toolPointQuery pToolPointQuery.OnCreate(Me.AxMapControl1.Object) Me.AxMapControl1.CurrentTool = pToolPointQuery 最后删除对变量 nMouseFlag 的定义即可。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 42 - 3.5.4 运行 图 49 程序运行结果 如上图所示,首先点击“点查询”按钮,鼠标形状会变成十字丝,之后点击相应的州 会弹出该州的名称。同时点击“居中放大”按钮会将地图放大。 3.5.5 小结 在这一小节中,我们学习了如何制作 BaseTool,正如同前一小节的小结中写到的那样, 当有许多功能(例如拉框放大,点查询等)时,由于 BaseTool 在生成的时候会自动和 MapControl 控件关联起来,故无需再自己添加变量来判断用户的选择,同时我们发现, MapControl 控件的 OnMouseDown 函数下并没有书写任何代码,这样使程序清晰易懂且减 少出错的可能。 在生成toolPointQuery.vb的同时,也生成了toolPointQuery.bmp和ToolbarControl.cur, 分别是一个位图文件和光标文件。与 BaseCommand 一样,位图文件对应的是出现在 ToolbarControl 控件中相应按钮的图标,而光标文件则是使用该工具的时候,鼠标在地图上 出现的光标形状。您可以双击位图文件或者光标文件,利用 Visual Studio 2005 提供的工具 编辑,也可以用自己喜爱的文件进行替换(请注意保持文件名的一致)。请您试着使用 ToolbarControl,使用其自带的 AddItem 方法将我们这一小节学习的 BaseTool 工具写入到 工具栏中,看能否实现点查询的功能。如果您对这一小节的内容比较熟悉了,就可以开始学 习本章最后一小节的内容了。在下一小节中,我们将尝试构建一个小型 GIS 应用。 3.6 通过代码添加图层 为了使得程序更加灵活,我们需要在程序运行后动态的向 MapControl 中添加图层。如 何通过代码来添加地图是在本小节需要学习的。 3.6.1 代码添加 MXD 文件 MXD 文件是 ArcMap 产生的地图索引文件,需要注意的是 MXD 文件并不含有地图数 据。打开 MXD 文件比较简单。核心代码如下,其中需要先在工程中用工具栏添加公共对话 框控件 OpenFileDialog。 需要注意的是,应为 MXD 文件只是 个索引文件。在测试这部分程序时,你需要用 ArcMap 生成一个新的 MXD 文件。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 43 - Dim sFilePath As String '调用OpenFileDialog,获取文件路径并打开地图文件 OpenFileDialog1.FileName = "" OpenFileDialog1.Title = "打开地图文件" OpenFileDialog1.Filter = "MapDocument (*.mxd)|*.mxd" If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then sFilePath = OpenFileDialog1.FileName If Not sFilePath = "" Then Me.AxMapControl1.LoadMxFile(sFilePath) End If End If Me.AxMapControl1.Extent = Me.AxMapControl1.FullExtent 3.6.2 通过代码加载 GeoDatabase 中的数据 Geodatabase 是 ESRI 在 ArcGIS9 版本中提出的基于 Access 数据库的数据存储结构。一般有 FileGeodatabase 和 PersonalGeodatabase,本小节中所使用的是 PersonalGeodatabase.注意下面 的代码为核心代码,这并不说明直接复制和粘贴可以使用的,你需要在你的程序中作出健壮 性判断,才能保证 Geodatabase 的路径不为空、图层文件名不为空。代码中 PathStr 变量存 储的是 Geodatabase 在磁盘上的位置,而 Filename 变量则是 Geodatabase 中需要打开的 图层名称。详细的代码请参看我们所提供的例子程序中的”通过代码添加图层” 3.6.2.1 从 GeoDatabase 数据库中添加矢量数据 Dim pWorkspace As IWorkspace pWorkspace = Nothing Dim pPropset As IPropertySet pPropset = New PropertySet Dim pFact As IWorkspaceFactory pPropset.SetProperty("DATABASE", PathStr) pFact = New AccessWorkspaceFactory pWorkspace = pFact.Open(pPropset, 0) Dim pFeatureLayer As IFeatureLayer Dim pFWorkspace As IFeatureWorkspace Dim pLayer As IGeoFeatureLayer pFWorkspace = pWorkspace pFeatureLayer = New FeatureLayer pFeatureLayer.FeatureClass = pFWorkspace.OpenFeatureClass(Filename) pFeatureLayer.Name = Filename pLayer = pFeatureLayer AxMapControl1.AddLayer(pFeatureLayer) Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 44 - 3.6.2.2 从 GeoDatabase 数据库中添加栅格数据 Dim pPropset As IPropertySet pPropset = New PropertySet Dim pFact As IWorkspaceFactory pPropset.SetProperty("DATABASE", PathStr) pFact = New AccessWorkspaceFactory pWorkspace = pFact.Open(pPropset, 0) Dim pRasterWorkspace As IRasterWorkspaceEx pRasterWorkspace = pWorkspace Dim pRasterDataset As IRasterDataset = Nothing pRasterDataset = pRasterWorkspace.OpenRasterDataset(Filename) Dim pRasterLayer As IRasterLayer = New RasterLayer pRasterLayer.CreateFromDataset(pRasterDataset) pRasterLayer.Visible = True Me.AxMapControl1.AddLayer(pRasterLayer) 3.7 基于比例尺显示地图 电子地图的最大特点之一在于,当地图比例尺比较小时,地图上所显示的地物应该相对 较少,当地图比例尺增大时,地图上的地物应当丰富起来。这就需要我们在比例尺变化时进 行地图切换。这一小节我们将学习如何基于比例尺来显示地图。 3.7.1 添加控件 新建一个 VB.NET 工程,向其中添加 Mapcontrol、LicenseControl、ToolsbarControl 。 如下图所示: 向 toolBarControl 中加入放大缩小等按钮。如下图所示: Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 45 - 3.7.2 添加引用和代码 首先添加引用。点击菜单栏上的“项目”—>“添加引用”,在弹出的对话框中同时选择 “ESRI.ArcGIS.Carto”、“ESRI.ArcGIS.Geodatabase” “ESRI.ArcGIS. DataSourcesGDB”” ESRI.ArcGIS.esriSystem” 并在代码区的顶端添加: Imports ESRI.ArcGIS.Geodatabase Imports ESRI.ArcGIS.DataSourcesGDB Imports ESRI.ArcGIS.esriSystem Imports ESRI.ArcGIS.Carto 利用上一小节所讲的内容,我们通过代码来添加图层。注意该小节的数据在示例数据中, 将“基于比例尺显示地图数据”文件夹下的 Goedatabase,拷贝到新建工程的 Bin\Debug\ 下 添加载入地图代码: Public Sub LoadMap() Try Dim pWorkspace As IWorkspace pWorkspace = Nothing Dim PathStr As String PathStr = System.IO.Directory.GetCurrentDirectory + "\New Personal Geodatabase.mdb" Dim pPropset As IPropertySet pPropset = New PropertySet Dim pFact As IWorkspaceFactory pPropset.SetProperty("DATABASE", PathStr) pFact = New AccessWorkspaceFactory pWorkspace = pFact.Open(pPropset, 0) Dim pFWorkspace As IFeatureWorkspace pFWorkspace = pWorkspace Dim pFeatureLayer As IFeatureLayer pFeatureLayer = New FeatureLayer pFeatureLayer.FeatureClass = pFWorkspace.OpenFeatureClass("Boundary3000") pFeatureLayer.Name = "Boundary3000" Dim pLayer As IGeoFeatureLayer pLayer = pFeatureLayer pLayer.MaximumScale = 3000000 AxMapControl1.AddLayer(pFeatureLayer) pFeatureLayer = New FeatureLayer pFeatureLayer.FeatureClass = pFWorkspace.OpenFeatureClass("Boundary500") pFeatureLayer.Name = "Boundary500" pLayer = pFeatureLayer pLayer.MinimumScale = 3000000 AxMapControl1.AddLayer(pFeatureLayer) Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 46 - Catch ex As Exception MsgBox("Open File Error!") End Try End Sub 在 Form1 的 FormLoad 中调用 LoadMap 函数 运行工程,我们会发现,开始显示的图层是 Boundary3000,当我们逐步放大地图后,当比 例尺大于 1:3000000 时 Boundary500 才会显示出来。如下图所示: 3.7.3 代码解释 关键代码是我们在向控件添加图层的过程中,设定了地图显示的最大比例尺和最小比例 尺。如我们在加载 Bourdary3000 中设定其最大比例尺为 1:3000000, “pLayer.MaximumScale = 3000000”当比例尺大于这个值时,Bourdary3000 就不会显示了。 同样我们设定了 Bourdary500 的最小比例尺为 1:3000000,“pLayer.MinimumScale = 3000000” 当比例尺小于这个值时,Bourdary500 就不显示。 3.7.4 小结 该小节我们在加载地图的过程中控制了地图的显示比例尺,如果你想了解更多关于地图 显示的东西,你可以再开发帮助中找到答案。 3.8 构建一个简单的 GIS 应用 在这一小节中,我们不会再像前五小节一样,只是针对某个具体的功能,而是将构建 一个初具规模的小型 GIS 应用。强烈建议您在开始这小节的学习之前,再次熟悉之前的几 个小节,这样对于您掌握这一小节的内容是十分有帮助的。在这一小节中,我们的重点是如 何利用 Visual Basic.NET 迅速搭建其一个 GIS 应用,也即框架的搭建,而不是具体某个功 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 47 - 能如何实现,所以对这一小节中所有的代码不再给出解释,请您自行参照帮助系统了解各接 口的详细定义与使用方法。我们展示的例子中,有些类似功能在实际开发过程中不会采用这 一小节中展示的方式,但这样能更好的向您介绍第三章最后一部分提到的一些拓展控件。 在构建小型 GIS 应用的过程中,首先应该做需求分析和功能设计,再进行用户界面的 设计,之后进行程序框架搭建和具体的编码工作,最后完成测试和维护。 3.8.1 功能概述 之前我们所做的程序都是在 MapControl 中预先加入数据,这一小节中,我们将改变这 一做法,制作与数据无关的程序。在这个程序中,我们将按照 Windows 程序的一般特征, 添加菜单栏和工具栏,并且使用控件的 Dock 属性,实现控件尺寸的缩放,也即当窗体尺寸 缩放时控件的尺寸也会随之缩放(我们之前书写的程序,当改变主窗体尺寸的时候,控件的 尺寸和位置不会改变);同时我们也将添加新的窗体,实现窗体间的调用。 3.8.2 新建及整理工程 在这一小节中,我们将新建一个工程,我们将这个工程命名为“MyGIS”。进入 MyGIS 工程编辑界面之后,我们看到解决方案资源管理器。右键点击 MyGIS,在弹出的右键菜单 中点击“添加”—>“新建文件夹”,将新加入的文件夹命名为“Classes”。重复这项工作,再加 入 名 为“Forms” 、“Modules”和“Resources”的 三 个文 件 夹 , 并 将 Form1.vb 重 命名 为 frmMain.vb,移动到 Forms 文件夹下。再在 Modules 文件夹上右键单击鼠标,选择“添 加”—>“新建项”,在弹出的对话框中选择Visual Basic项中的模块,采用默认命名Module1.vb, 整理好之后的解决方案资源管理器如下所示: 图 50 解决方案资源管理器 这样做的好处是将类,窗体,资源文件和模块分门别类,方便管理。这里值得说明的 是,模块的作用一般是用来存放全局变量以及一些公共函数,在模块中定义的公共变量和公 共函数可以直接使用而不用在变量或者函数前加类名。 3.8.3 添加菜单栏 添加菜单栏,在属性窗口中点击 Items 项右侧的按钮,弹出如下对话框: Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 48 - 图 51 菜单栏的项集合编辑器 首先添加一级菜单。点击窗体上方的“添加”按钮三次,加入三个 MenuItem,并将其 Name 属性分别修改为“mnuFile”,“mnuMapView”和“mnuQuery”,将其 Text 属性分别修改 为“文件”,“地图浏览”,“查询”。得到如下结果: 图 52 菜单控件外观 然后用第三章中介绍的方法,选择某个菜单项的 DropDownItem 属性,用类似方法为 菜单添加二级项目。如下所示(汉字为 Text 属性,省略号表示下一级菜单,括号内为 Name): 文件(mnuFile) ……打开(mnuFileOpen) ……退出(mnuExit) 地图浏览(mnuMapView) ……中心放大(mnuFixedZoomIn) ……中心缩小(mnuFixedZoomOut) ……任意比例尺放大(mnuZoomIn) ……任意比例尺缩小(mnuZoomOut) ……漫游(mnuPan) ……全图显示(mnuFullExtent) 查询(mnuQuery) ……属性查询(mnuAttributeQuery) ……空间查询(mnuSpatialQuery) ……点查询(mnuPointQuery) ……矩形查询(mnuRectangleQuery) Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 49 - 制作好的工具栏如下所示: 图 53 制作好的菜单控件 3.8.4 添加工具栏 向主窗体中添加工具条(ToolStrip),点击工具栏属性表中 Items 项右侧的按钮,弹出 如下对话框: 图 54 工具栏的项集合编辑器 向其中添加六个按钮,属性设置如下: 图标 Name Text tlbFixedZoomIn 居中放大 tlbFixedZoomOut 居中缩小 tlbZoomIn 任意比例尺放大 tlbZoomOut 任意比例尺缩小 tlbPan 漫游 tlbFullExtent 全图显示 制作好的工具栏如下图所示: 图 55 制作好的工具栏 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 50 - 3.8.5 添加控件 在工具栏中找到 SpliterContainer 控件, ,在 frmMain 窗体中添加一 个。得到的默认布局为竖直布局,左侧为 Panel1,右侧为 Panel2,如下图所示: 图 56 添加好 SpliterContainer 控件后的窗体布局 在 Panel2 中添加一个 MapControl 控件和 LicenseControl 控件。找到 MapControl 控 件中的 Dock 属性,点击其中的正方形,将 Dock 属性设置为 Fill,如下图所示: 图 57 MapControl 的 Dock 属性 向 Panel1 中添加一个 TabControl 控件( ),将其 Dock 属性设为 Fill, 将 Alignment 设置为 Bottom,并点击 TabPages 属性右侧的 Buttton,弹出 TabPage 集合 编辑器,将 TabPage1 的 Text 属性设置为“图层”,将 TabPage2 的 Text 属性设置为“属性字 段”。 在 IDE 中,点击 TabControl 控件的“图层”页,将控件翻到这一页,向其中添加一个 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 51 - CheckedListBox 控件( ),将其 Dock 属性设置为 Fill,再点击“属性字 段”页,将 TabControl 控件翻到第二页,向其中添加一个 ListBox 控件( ), 同样将其属性字段设置为 Fill。 制作好的界面暂时如下图所示: 图 58 制作好的程序界面(IDE 中) 3.8.6 添加类 与上一小结介绍的类似,将鼠标移动到解决方案资源管理器,鼠标右键点击 Classes 文件夹,再点击弹出菜单的“添加”——“新建项”,选择 ArcGIS 项中的 Base Tool,将名字更 改为 toolZoomIn.vb,添加即可。 之后在解决方案资源管理器中,将 toolZoomIn..bmp 和 toolZoomIn.cur 移动到 Resources 文件夹下。现在您可以双击 toolZoomIn.cur,在弹出的界面中手动修改图标(这 个图标是当用户选择了 toolZoomIn 工具之后,出现在 MapControl 控件中的鼠标形状),也 可以使用已有的鼠标形状对其进行替换。在提供的实习资料文件夹中找到 Resources 文件 夹,从其中将 toolzoomin.cur 文件找出来,对您自己工程文件夹下 Resources 文件夹中的 相应文件进行替换(如果文件名不一致,则将自己工程下的文件删除,替换了新的文件后修 改文件名保持和原先以后的文件名一致)。替换之后,将该文件属性中的类型更改为“嵌入的 资源”,并点击菜单栏中的“生成”—>“重新生成解决方案”,这样能更新替换之后的图标文件 (如果直接在 Visual Basic.NET IDE 中修改则不需要这一步)。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 52 - 之后我们点击 toolZoomIn.vb,如下图,对 m_toolTip 和 m_name 做相应修改。 图 59 toolZoomIn.vb 中修改项 再向其中的 OnMouseDown 函数添加如下代码: frmMain.AxMapControl1.Extent = frmMain.AxMapControl1.TrackRectangle 这样就完成了 toolZoomIn.vb 类的制作。在下面的程序中,调用这个类,即可完成“任 意比例尺放大”的功能。 按照之前两个小节讲述的做法,完成其余类的制作,具体方法这里不一一列举出,您 可以参考提供的例子程序 MyGIS,详细查看其中每一个类的制作方法,代码方面的问题如 果有疑问,可以参看帮助系统,具体帮助系统的使用方法在第六章中有详细讲述。 3.8.7 添加新的窗体 现在我们将添加一个新的窗体,来显示查询得到要素的属性表。 在解决方案资源管理器中,右键点击 Forms 文件夹,在弹出的菜单中,选择“添加” —>“新建项”,在弹出如下对话框: 图 60 添加新窗体 在左侧的类别中选择 Visual Basic 项,在右侧选择 Windows 窗体,将名称修改为 frmTable.vb,点击“添加”。之后将 frmTable.vb 的 Text 属性修改为“属性表”,将 TopMost 属 性修改为 True。向其中添加一个 MSHFlexGrid 控件( ),将其 Dock 属性设置为 Fill。 这个控件需要手动添加,点击工具箱,滑动滚动条至最下一行,在“常规”项的下方右键 单击,在弹出的菜单中点击“选择项…”,弹出如下对话框,在“COM 组件”上单击,切换到第 二页,找到其中的 Microsoft Hierarchical FlexGrid Control6.0 项,在前面打勾即可。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 53 - 图 61 添加控件 3.8.8 添加引用和代码 至此,程序的框架已经搭建完毕,我们来依次完成一些简单的功能。 1)地图数据的读入 添加一个 OpenFileDialog,再单击菜单控件上的“文件”选项,并选择二级菜单中的“打 开”,双击“打开”,进入代码编写界面。向其中添加如下代码: Dim sFilePath As String '调用OpenFileDialog,获取文件路径并打开地图文件 OpenFileDialog1.FileName = "" OpenFileDialog1.Title = "打开地图文件" OpenFileDialog1.Filter = "MapDocument (*.mxd)|*.mxd" If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then sFilePath = OpenFileDialog1.FileName If Not sFilePath = "" Then Me.AxMapControl1.LoadMxFile(sFilePath) End If End If Me.AxMapControl1.Extent = Me.AxMapControl1.FullExtent '将每个图层的名字依次添加到CheckedListBox1控件中,并根据图层的可见性设置是否打勾 CheckedListBox1.Items.Clear() Dim i As Integer For i = 0 To Me.AxMapControl1.LayerCount - 1 CheckedListBox1.Items.Add(Me.AxMapControl1.Map.Layer(i).Name, Me.AxMapControl1.Map.Layer(i).Visible) Next Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 54 - 2)添加退出及释放控件功能 单击菜单控件上的“文件”,在二级菜单中双击“退出”,进入代码编写界面,向其中 添加“Me.Close()”。 之后在代码编写界面中的类名下拉列表框中选择(frmMain 个事件),如下图所示: 图 62 frmMain 个事件 再在右侧的方法名称中选择 FormClosing 方法,向其中添加如下代码: 图 63 FormClosing 方法 Me.AxMapControl1.ClearLayers() ESRI.ArcGIS.ADF.COMSupport.AOUninitialize.Shutdown() 3)控制图层可见性及获取图层属性字段 向 工 程 添 加 引 用 “ESRI.ArcGIS.Carto” 和 “ESRI.ArcGIS.Geodatabase” , 并 在 frmMain.vb 中添加这两个引用,也即在所有代码的最前面添加如下语句: Imports ESRI.ArcGIS.Carto Imports ESRI.ArcGIS.Geodatabase 在 IDE 中进入 frmMain.vb 的设计界面,找到 CheckedListBox1 控件,双击进入代码编 写界面,默认方法为“SelectedIndexChanged”,向其中添加如下代码: Dim i As Integer i = CheckedListBox1.SelectedIndex If i < 0 Then Exit Sub Dim pFeatureLayer As IFeatureLayer pFeatureLayer = Me.AxMapControl1.Map.Layer(i) Dim pFeatureClass As IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass '将属性遍历一遍,名字添加到ListBox1控件中 ListBox1.Items.Clear() For i = 0 To pFeatureClass.Fields.FieldCount - 1 ListBox1.Items.Add(pFeatureClass.Fields.Field(i).Name) Next 在该控件的方法中找到“SelectedValueChanged”方法,向该方法添加如下代码: '获取当前选择项是否选中,并决定相应图层是否可见 Dim i As Integer i = CheckedListBox1.SelectedIndex Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 55 - If CheckedListBox1.GetItemChecked(i) Then Me.AxMapControl1.Map.Layer(i).Visible = True Else Me.AxMapControl1.Map.Layer(i).Visible = False End If Me.AxMapControl1.Refresh() 4)添加地图浏览功能 按照前两小节介绍过的方法,类似的,双击工具栏控件中的第一个按钮,进入该按钮 的代码编辑界面。向默认方法中添加如下代码: '实例化一个“顶比例尺放大”类 Dim pcmdFixedZoomIn As New cmdFixedZoomIn '创建这个类,并与MapControl控件关联起来 pcmdFixedZoomIn.OnCreate(Me.AxMapControl1.Object) '调用OnClick事件,相当于触发该命令 pcmdFixedZoomIn.OnClick() 类似的,将菜单栏和工具栏中所有涉及到地图浏览功能的代码补齐,具体方法这里不 再赘述,您可以参看之前两小节讲述的方法,也可以参考实习资料中的例子程序。 5)添加属性查询的功能 之前我们已经查询得到了每个属性字段的名称,所以您可以借助这个功能继续深入的 挖掘属性查询的功能,这里我们就不详细讲述具体的方法。如果有疑问,您可以参考之前小 节中介绍的属性查询的方法,也可以借助帮助系统。这里给您一些有用的提示,您可以尝试 着首先判断属性字段的类型,因为对字符串和对数值的查询方法是不一样的。另外,您需要 研究一下查询条件中的 WhereClause 语句该如何书写,因为属性查询的根本也就是在书写 WhereClause 语句上,其方式类似于 SQL 查询语句,也支持模糊查询等。 6)空间查询功能的实现 接下来我们要完成最后一步——空间查询,我们在前面的基础上再添加一个矩形查询 的功能。由于点查询的功能之前已经讲过,这里就不再赘述。需要注意的是,具体的代码发 生了一些变化,因为这里我们将公共函数写入了 Module1 中,另外就是我们要弹出查询结 果的属性表。 下面我们详细讲述矩形查询的方法,关于点查询,您可以参考例子程序中的相关代码。 首 先 打 开 Module1.vb , 向 其 中 添 加 引 用 “ESRI.ArcGIS.Carto” , “ESRI.ArcGIS.Geomtery”和“ESRI.ArcGIS.Geodatabase”,将引用添加在模块的最上方,如 下所示: Imports ESRI.ArcGIS.Carto Imports ESRI.ArcGIS.Geometry Imports ESRI.ArcGIS.Geodatabase 再向 Module1 中添加如下函数: Public Sub SelectRectangle(ByVal pGeometry As IGeometry) Dim pFeatureLayer As IFeatureLayer Dim pFeatureClass As IFeatureClass Dim pSpatialFilter As ISpatialFilter Dim pFilter As IQueryFilter Dim pActiveView As IActiveView Dim str As String Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 56 - Dim n As Long Dim i As Integer Dim pCursor As IFeatureCursor Dim pFeature As IFeature str = "" frmMain.AxMapControl1.Map.ClearSelection() Try '根据图层控制中选择的相应图层来做查询 i = frmMain.CheckedListBox1.SelectedIndex If i < 0 Then Exit Sub '如果该图层不可见,则首先让其可见 If Not frmMain.AxMapControl1.Map.Layer(i).Visible Then frmMain.AxMapControl1.Map.Layer(i).Visible = True frmMain.CheckedListBox1.SetItemChecked(i, True) End If pFeatureLayer = frmMain.AxMapControl1.Map.Layer(i) pFeatureClass = pFeatureLayer.FeatureClass If pFeatureClass Is Nothing Then Exit Sub pActiveView = frmMain.AxMapControl1.Map '书写查询器 pSpatialFilter = New SpatialFilter pSpatialFilter.Geometry = pGeometry Select Case pFeatureClass.ShapeType Case esriGeometryType.esriGeometryPoint pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains str = "Point" Case esriGeometryType.esriGeometryPolyline pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses str = "Polyline" Case esriGeometryType.esriGeometryPolygon pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects str = "Polygon" End Select pSpatialFilter.GeometryField = pFeatureClass.ShapeFieldName pFilter = pSpatialFilter pCursor = pFeatureLayer.Search(pFilter, False) pFeature = pCursor.NextFeature i = 0 '获取查询得到的要素总数 While Not pFeature Is Nothing i = i + 1 pFeature = pCursor.NextFeature End While Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 57 - pCursor = pFeatureLayer.Search(pFilter, False) pFeature = pCursor.NextFeature If Not pFeature Is Nothing Then '清除表并设置行列数 frmTable.AxMSHFlexGrid1.Clear() frmTable.AxMSHFlexGrid1.set_Cols(pFeature.Fields.FieldCount) frmTable.AxMSHFlexGrid1.Rows = i + 1 '添加标题 For n = 0 To frmTable.AxMSHFlexGrid1.get_Cols - 1 frmTable.AxMSHFlexGrid1.set_TextMatrix(0, n, pFeatureClass.Fields.Field(n).AliasName) Next n i = 1 '添加内容 While Not pFeature Is Nothing frmMain.AxMapControl1.Map.SelectFeature(pFeatureLayer, pFeature) For n = 0 To frmTable.AxMSHFlexGrid1.get_Cols - 1 If n <> 1 Then frmTable.AxMSHFlexGrid1.set_TextMatrix(i, n, pFeature.Value(n).ToString) Else frmTable.AxMSHFlexGrid1.set_TextMatrix(i, n, str) End If Next n pFeature = pCursor.NextFeature i = i + 1 End While pActiveView.Refresh() frmTable.Show() Exit Sub End If Catch ex As Exception MessageBox.Show(Err.Description, "Wrong", MessageBoxButtons.AbortRetryIgnore) End Try frmMain.AxMapControl1.Refresh() End Sub 类似的,新建一个 ArcGIS 的 BaseTool,命名为 toolRectangleQuery,类似的,按下 图修改一些基本信息 再在 OnMouseDown 函数中添加如下代码 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 58 - SelectRectangle(frmMain.AxMapControl1.TrackRectangle) 最后点击菜单栏控件中的查询,点击空间查询,再双击下一级菜单中的“矩形查询”,进 入代码编辑界面,添加如下代码: Dim ptoolRectangleQuery As New toolRectangleQuery ptoolRectangleQuery.OnCreate(Me.AxMapControl1.Object) Me.AxMapControl1.CurrentTool = ptoolRectangleQuery 这样就完成了空间查询中的矩形查询功能。在查询的时候,需要在左侧的图层控制列 表框中选中要查询的图层,再在地图上拉框即可。 3.8.9 小结 在这一小节中,我们将前几节的知识整合起来,完成了一个小型 GIS 应用程序的制作。 这个程序能够完成地图载入,地图浏览以及基本图层控制和查询功能。正如之前讲到的,这 一小节的重点在于如何构建一个 GIS 应用而不在于具体功能的实现,如果您要完成更加强 大的功能,可以参考第 6 章的相关内容,也可以通过第 5 章的学习,借助帮助系统完成一 些新功能的开发。 这一小节中涉及的代码难度都不是特别大,许多都是之前小节讲解过的,但仍然推荐 您仔细结合例子程序查看代码,毕竟这一章节的组织结构与之前的不一样,代码上也会有些 变化。如果需要获得进一步的信息,请查看帮助系统。 4.问题解决方法及帮助文档的使用 ArcObjects 开发帮助系统(ArcObjects Developer Help System)对初学者和有开发经 验的开发者来说都是必要的资源。它能提供给您每个类、接口的说明文件,以及一些示例代 码、技术文档和对象模型图。 4.1 使用 ArcObjects 开发帮助系统 需要启动 ArcObjects 开发帮助系统,您可以点击“开始”按钮,点击“程序”,指向“ArcGIS”, 然后点击“ArcObjects Developer Help”,最后点击“.NET Help for VS2005”。(与“.NET Help for VS2005”类似,“ArcGIS Desktop Help for VB6 Developers”也是帮助系统,内容与前者 大同小异,您也可以尝试使用后者,下文以前者为例) 图 64 ArcObjects 开发帮助系统路径 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 59 - 图 65 帮助系统封面 点击左下角的“目录”按钮,在左侧的树结构目录中找到需要的主题,之后单击标题,则 会在右侧的内容显示窗口内看到该主题的详细内容。例如上图展示了点击“What is ArcGIS Desktop?”之后的内容,右侧就有关于这个主题的详细介绍。 当需要搜索某一个主题(例如某个接口、变量)的时候,可以点击左下角的“索引”按钮, 之后在“查找”文本框中输入自己感兴趣的内容即可。下面以搜索“IFeatureClass”为例详细讲 述帮助系统的使用方法。 图 66 搜索 IFeatureClass 得到的结果 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 60 - 将右侧的内容详细的展示出来,如下所示(其中“…”表示内容略去): ArcGIS Developer Help (ESRI.ArcGIS.Geodatabase) IFeatureClass Interface Provides access to members that control the behavior and properties of a feature class. Product Availability Available with ArcGIS Engine, ArcGIS Desktop, and ArcGIS Server. When To Use The IFeatureClass interface is the main interface for getting and setting properties of a feature class. For example, use the IFeatureClass interface to get the type of feature class, get a count of features that satisfy some query, or create a new feature in the feature class. The IFeatureClass interface inherits from the IObjectClass interface. Members Name Description … … Inherited Interfaces Interfaces Description … … Classes that implement IFeatureClass Classes Desription … … [C#] //e.g., nameOfFeatureClass = "states"; //on ArcSDE use ISqlSyntax::QualifyTableName for fully qualified table names. public IFeatureClass getIFeatureClass(IWorkspace workspace, string nameOfFeatureClass) { //cast for the feature workspace from the workspace IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace; //open the featureclass return featureWorkspace.OpenFeatureClass(nameOfFeatureClass); } See Also IClass Interface | IObjectClass Interface | INetworkClass Interface Example IFeatureClass Example 下面我们来详细讲解每个小标题的内容: 标题是“ArcGIS Developer Help (ESRI.ArcGIS.Geodatabase)” IFeatureClass Interface 这表明 IFeatureClass 接口是包含在 ESRI.ArcGIS.Geodatabase 这个类库中,在编程 的时候,如果想使用 IFeatureClass 接口,则需要首先添加“ESRI.ArcGIS.Geodatabase” 的引用,也就是加上“Imports ESRI.ArcGIS.Geodatabase”之类的引用。这样,当您需要 使用别的接口时,首先就需要查询帮助,并将您需要的引用添加到程序中,这也是我们之前 编写程序需要添加一些不同引用的原因。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 61 - 标题下面的第一行是“Provides access to members that control the behavior and properties of a feature class.”,这表明,IFeatureClass 接口提供了访问控制要素类行为和属性成员的的方 法。类似这样的话能够让您迅速明白某个接口的作用。 “Product Availability”指的是产品的使用范围,这里从紧接这的介绍可以清晰地看 到,在 ArcGIS Engine,ArcGIS Desktop 和 ArcGIS Server 中都可以使用。 “When To Use”指的是使用这个接口的场合,也可以算接口的综述。从紧跟着的介 绍性文字可以得出,“IFeatureClass 接口是获得和设置要素类属性的主要接口。例如,使用 IFeatureClass 接口能够得到要素集的类型,获得满足某种查询条件的要素数量,或者是在 要素集中创建一个新的要素。IFeatureClass 接口从 IObjectClass 接口继承而来。” “Members”指的是接口下的成员,这包括属性、方法等。这里我们不能一一给您列 举出来,而是挑选一个作为例子讲解。 例如我们看到“Search”成员,这是一个方法,通过对“Search”的描述,我们可以得到, “Search”方法将“返回一个 object cursor,其中包含经过特定的查询条件得到的要素对象”。 通过这个描述,我们可以大概得出,通过“Search”方法,我们可以从一个要素集中按照一定 的查询条件得到一些特定的要素,供后续使用。为了获得更加详细的描述,我们点击 “Search”,选取其中对我们讲解有用的部分,如下所示: [Visual Basic .NET] Public Function Search ( _ ByVal filter As IQueryFilter, _ ByVal Recycling As Boolean _ ) As IFeatureCursor 这部分给出了 VB.NET 中的函数定义,其中包含两个传入参数和一个返回值,传入参 数分别是 IQueryFilter 类型的 filter 和布尔型变量 Rechcling,返回值是 IFeatureCursor 类型 的变量。 下面是参数详解: Parameters filter [in] filter is a parameter of type IQueryFilter Recycling [in] Recycling is a parameter of type VARIANT_BOOL Cursor [out, retval] Cursor is a parameter of type IFeatureCursor 之后的“Remarks”提供了一些值得注意的地方,并给出了使用方面更加详细的介绍,这 里就不一一列举了。关于其中的参数如何使用,如何设置,可以继续搜索“IQueryFilter”(这 个接口将告诉您如何书写查询条件)和“IFeatureCursor”(这个接口将告诉您如何获取查询 结果并读取其中的内容)等,方法与之前介绍的类似。 回到 IFeatureClass 的帮助,在“Members”之后是“Inherited Interfaces”和“Classes that implement IFeatureClass”,分别标明了 IFeatureClass 接口是从何继承而来以及实现了 IFeatureClass 接口的类,根据 COM 的标准,您可以通过 COM 原理中的 QueryInterface, 从 IFeatureClass 接口查询得到实现了该接口的其他接口。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. ArcEngine 二次开发实习初级讲义 - 62 - 后面的“See Also”代表了与此相关的一些接口,“Example”(如果有的话)就是具体的 示例代码,通过这些示例,相信您能更快的熟悉接口的使用。 请您参照帮助系统,熟悉 IMapControl2,IActiveView,IFeatureLayer,IFeatureClass, ISpatialFilter,IFeatureCursor,IFeature,IGeometry 等接口,以及这些接口中的属性、方 法等涉及到的其他接口。熟悉和掌握这些常用接口的使用,对您熟悉 ArcObjects 与迅速掌 握 ArcObjects 的开发是极有帮助的。 4.2 阅读对象模型图(Object Model Diagram) 图 67 对象模型图 如上图所示,对象模型图展示了每个对象内的各类之间的接口,继承、派生关系,属性 及方法之间的联系等,是对整个对象最完整的定义。对象模型图可视化的表达了 ArcObjects 的继承关系,因而您能识别关键对象,查看哪些对象之间具有联系(如对象的创建关系), 理解接口继承和派生类型的定义,并且找出实现了一个类所实现的全部接口。参考对象模型 图与参看帮助系统中具体的接口所获得的信息是一致的,只不过查看具体的接口信息将更方 便获得具体的使用方法,属性设置方法等,而参看对象模型图是从全局来把握整个对象,更 容易找出各接口之间的联系和调用方式等。 对象模型图的放置路径为“X:\Program Files\ArcGIS\DeveloperKit\Diagrams”(X 代表 ArcGIS 安装所在的盘符)。 对象模型图的书写类似于 UML 图,对象模型图中也对其基本规则也有所解释,因而 UML 的具体语法规则、定义等这里不再赘述,如果需要更加详细的信息,您可以参考 UML 方面的相关书籍,或者参考《Exploring ArcObjects》中的相关章节。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only.
还剩61页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

我是大爷

贡献于2017-03-15

下载需要 10 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf