前奏
ArcGis
首先,很多一开始接触ArcGis的人总以为它是一个应用程序。很遗憾这种理解是片面,甚至说是不对的。
ArcGis is a Family. 它是一个家族,是N多个应用程序的集合――-包括客户端软件、服务器端软件等等
ArcView
然后,很多一开始接触ArcView的人又以为它应该是一个应用程序。很遗憾这种理解又是片面的,甚至说又是不对的。
ArcView is a Aggregation. 它是一个应用程序的集合体―――包括Arcmap、ArcCatalog、Arctoolbox三个应用程序。
主旋律
进入正题前,我们还是有必要看一下已经泛滥的一张图片:
(Pic From <AO 初探>)
ArcMap (core and layer objects)
鉴于大家在这次开发中可能很少涉及关于Page、Element、Mapsurround等Object,所以这里只是稍微就自己的一字半解来讨论一下Core And Layer Objects。
Core object
Core object并不是一个Object,它是指在Arcmap中核心的几个Objects。从中我又挑出了最重要也是最常用的三个Object:Application、MxDocument、Map。需要指出的是Application (要是大家以前碰过V
BA,一定不会对Application这个对象陌生的)、以及MxDocument (Mx前缀表示Arcmap的对象;Gx前缀表示ArcCatalog对象)这两个对象在VB里将不会碰到,它们只用于VBA定制。
下面的图片将会使这几个对象直观化:
小插曲1(COM)
COM不是一种语言,是一种类编程的标准。
l为什么使用COM?
原因很简单:面向对象;重用,重用再重用;无语言限制(它是一个二进制规范,跟使用什么语言无关)
Sample1:比如我们用VB编好了一个类,如果把它做成COM类,并编译成DLL,那么我们就可以在VC、C++、Delphi等任何语言中使用。
l为什么使用接口?
问题源于:当我们需要改变类的方法中实现过程,或者说其中的一些代码和一些参数设置的时候,如果不使用接口,你就只能像一个推销员一样,天天上门跟你的用户说:这里方法不是这么调用的。Maybe it’s cool,but everybody think it’s boring!
那么使用接口又会怎样呢?接口自从你在类设计的时候就规定死了,除非你把它删掉。用户不需要知道你这个类内部如何变化,他需要做的就是:拿起这把钥匙对准这个钥匙孔!Sample2:假如我们现在有
一个收音的接口:用来播放一些相声和笑话;现在用户提出笑话很无聊,想听音乐Mp3。那我们要做的就是改变其中的一些代码,而用户仍旧使用这个接
口,然后听到的将是美妙的音乐。
l该使用哪个接口?
视具体情况查阅:《Exploring AO》、OMD(Object Module Diagram)、VB中Object Viewer。
l QI (Query Interface)
这是在接口编程中经常使用的方法:同一个类的两个接口之间的查询。
Sample3:
比如有一个类A,它有I1、I2两个接口,那么我们可以:
Dim A1 as I1
Set A1=New A
Dim A2 as I2
Set A2=A1
(QI,我自己也是半天才搞明白的,我这也是今天讲的东西里面最有用途的『不好意思有点臭美了,说不定大家比我清楚的多,呵呵』。我想大家以后在AO编程中QI将会发挥它无穷的魅力)
末了,我有点惊讶,讲Com竟然没用一张图,COM大师们会不会过来扁我呢~~
言归正传,三个核心对象:
Application:When you first start ArcMap, the Application object is first created, and then it in turn instantiates all of the objects it manages.(From 《Exploring AO》)
意思很明确,当我们一打开Arcmap,Application对象将被创建,同时它所管理的对象也将被初始化或者说实例化。
所以,我们在VBA定制的时候就可以直接使用这个内建对象,不需要我们自己创建或者实例化。
MxDocument:The ArcMap application automatically creates this object when the application first starts. (From 《Exploring AO》)
同样,当我们一打开Arcmap,Application将自动创建一个新的MxDocument对象;而当我们自己打开一个已经存在Mxd文件时,Application中的MxDocument对象也将会改变。
得到它也只是一句代码的问题
Dim pMxd as IMxDocument
Set pMxd=Application.MxDocment
Map:这个对象的接口就复杂的多了。但我们这里只会去关心它的IActiveView和IMap.
关于IActiveView,我们从上面的图片中知道MxDocument中有两种视图:Dataview和PageLayout View,通过它,我们可以得到正在激活状态的视图。
关于IMap,我们同样也只在乎它激活状态的那张地图,也就是FocusMap。
很好,现在我们在这里可以回顾一下我们刚才说的重要部分QI:
Dim pMxd as IMxDocument
Set pMxd=Application.MxDocment
Dim pMap as IMap
Set pMap=pMxd.FocusMap
Dim pActive as IActiveView
Set pActive=pMap ‘QI
明显地,IActiveView、IMap是Map这个对象的两个接口,它们之间的查询是允许的。
这里,我能做的就是告诉大家怎么得到这些基本接口,接下来做什么当然是随你所好了:DO Everything You Want!
Layer Object
Map 是图层的一个集合,得到它就等于我们得到了这个Map下的所有图层。
Dim pMap as IMap
Set pMap=pMxd.FocusMap
Dim pLayer as ILayer
Set pLayer=pMap.Layer(0) ‘类似数组与成员之间的访问
有人肯定会不满于这种访问方式:要是不知道Layer的序号Index,只知道层名怎么办?
接口文档怎么看有这种疑问是肯定,而且是程序员必须的;同时我们可爱的程序员肯定会一厢情愿地想到:IMap 应该会提供一个诸如FindLayerByName的方法!
很遗憾Esri没有提供,考虑到这也是几行代码可以实现的,不需要去多加这个方法。
Sub FindLayerByName(strName as String) as ILayer
Dim pMap as IMap
Set pMap=pMxd.FocusMap
Dim i as Integer
For i=0 to pMap.LayerCount-1
If pMap.Layer(i).Name=strName Then
Set FindLayerByName =pMap.Layer(i)
Exit For
End If
Next i
End Sub
我想一个循环能解决的问题,自己动手写也是无妨。
Layer对象也是有很多接口,不过我也不想一一去列举了。
但要注意的是Esri把我们熟知的矢量图层称作要素图层(FeatureLayer),把栅格图层(RasterLayer)。(在ArcIms中要素流这个词是很形象的)
因此,我们得到一个图层的时候,有可能就要去判断是矢量还是栅格。
Vb中一个关键词就可以做到:Typeof
Dim pMap as IMap
Set pMap=pMxd.FocusMap
Dim pLayer as ILayer
Set pLayer=pMap.Layer(0)
Dim pFlayer as IFeatureLayer
Set pFlayer=pLayer
End if
小插曲2 Vb中的琐事
l命名的规范化
命名看来事小,其实要是你真的编了大段代码后,你就会猛然发现:啊,这个变量我把它定义成什么了;或者:嗯?这个变量我怎么重复定义了!等等。尤其是当你是在一个开发小组中,开发结束大家合并代码的时候,发现怎么大家定义了很多重复的全局变量!
关于全局变量,如果是一个开发小组,大家一定商量后在定义,以免发生重复,那将是一个小灾难!
大家从上面的代码中,会发现:为什么变量前都加一个小写的p?理由是我这里声明的变量都是过程级的(procedure);同样如果声明全局变量时,最好在前面加g(Global)。
l关于VB中的Set
很多VB的初学者对Set的使用很是茫然,慢慢地,他们发现一个基本规律:在基础数据类型赋值时,不使用Set(如整型、单精、双精、字符等等);在声明变量为一个接口或者一个类时,将使用Set(如上面代码中IMap、ILayer等等)。
当然这是没错,但是这有点只知其一,不知其二了:
Set其实做的事情―――引用(正如C++里面的引用),一旦你Set了,你得到的不是这个对象的复本,而是这个对象的引用,也就是说,你在任何地方改动它,都将影响到原对象的一些内部属性的值。
尾曲
最后,我突然发现自己的罗嗦已然是病入膏肓。该Stop了!
下面想带来的是一些开发的捷径(其实也算是我的一些以前开发时走过的弯路),希望大家少走弯路,选择自己的捷径(在Gis中我们叫最佳路径呵呵)
引用以前我在一个Gis论坛上发过的贴子:
<!--
我是想过ExploringAO,可能有这些例子,但是可能大家都不了解我的出发点:就是大家要某个简单功能的代码时,不用去翻1300多页的ExploringAo,举个简单的例子:ADDData这个工具,我们怎么去把AddData这个窗体调出来,我不相信你一下子在ExploringAo中能到!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论