絮语闲聊,权当消遣- 最近抽时间整理一些以前写的程序,也开始了解MO(ESRI MapObject)的应用,有些感受一起吐出。在GIS应用中最大的工作就是数据的采集整理了,虽然你可以采用MO、MAPX等一些地图控件(我曾经还看到过一个南非人用DEPHI写的地图控件,也是很有些特点的),如果你够超人,甚至可以自己去做一个地图控件,来完成一个实用性也很个性化的系统出来。可是它终究只是一个应用系统而已。 ???你应该知道我要讲什么的了吧。所有的应用都是基于一定的数据结构,你可以在自己的应用开发中定义数据模型,但是数据的来源呢。不是CAD,就是COVERAGE,SHAPE,(标准嘛)你可以针对一两种数据格式进行转换,只是现实中的数据类型是多样的,总不能都去写吧,况且你的数据格式能否得到认可呢。再想想看你要做多少工作---那是一个GIS平台才能完成的事情。这就是许多情形下我们为什么没法完全用底层或地图控件去写一个完整GIS系统主要的原因吧。
扯远了。。。在本章中,我会实现一个特定功能的DLL,用来说明AO开发的几种模式,AO工具包的使用,如何应用写好的组件。在ArcObjects Developer Help中有许多完整和详尽的示例代码,这儿主要想就方法做一个简要的说明。
4.1选择一个开发模式
AO可选的的开发方式可以分为两种,一种是在ArcMap应用框架基础上进行定制开发,另一种是脱离ArcMap应用框架去开发独立的应用程序。通常情况下,我们都是在ArcMap框架下进行定制开发。开发环境可以选择ArcMap本身自带的VBA,也可以选择VB、VC、DEPHI(AO 8.2以上的版本开始支持C#)。
4.2选择一个开发工具
作为首选的是VB语言,这样不管是在VBA,还是编写COM组件,你都有最充足的资源可以使用(AO开发文档中最多的SAMPLE就是VB代码了)。第二种是VC(我更愿意将VC做为一个强有力的后备工具),第三种在我看来应该是一种无奈之举了,即用DEPHI(有一堆人该贬我了:)一直对DEPHI是仰慕有加心仪已久的,只是在AO中有关DEPHI的例子太少了,这对快速应用开发来说是致命的)。
4.3最简单的“Hello,world”程序
讨论开发工具多少有点离题,现在让我们来转回到一个出名的小应用程序—“Hello,world”,许多语言都是以此做为第一个应用的,我也就不例外了。
打开ArcMap应用程序,选择TOOLS菜单下的MACROS子菜单,打开其中的VBA环境。选择Project工程下的ArcMap Object ,双击打开其中的ThisDocument对象,在右边的编辑环境中选择对象列表中的MxDocument对象,在任务列表中选择OpenDocumen,然后键入以下的代码:
//Private Function MxDocument_OpenDocument() As Boolean
Dim pmap As IMap
Set pmap = New Map
pmap.Name = "Hello,world"
MsgBox pmap.Name
//End Function
然后按CTRL+S保存后退出ArcMap。当你再次打开你所保存的工程文档时看到了什么?呵呵呵,不知道ESRI的设计人员看到这样的一个SAMPLE会不会晕掉。
有人说了,你这一堆VB代码对我来说我搞不懂啊,我熟悉的是VC,总不能让我先去学VB再来做AO开发吧。OK,没关系,下面我就以这个“Hello,world”来写一个组件并在ArcMap中来使用。
1. 启动VC,使用ATL COM AppWizard创建一个DLL工程;
2. 在INSERT菜单下选择NEW ATL OBJECT来增加一个ATL COM对象,
3. 给这个COM对象就起个“world”的名字吧,选择Custom接口类型(至于为什么不选择DUAL,你可以琢磨下)
4. 在工作空间上选择Cworld类,并右键选择Implement Interface,在类型库中引入ESRI OBJECT Library,选择你要实现的接口(这儿我们选择Icommand)
5. 增加一个全局变量(IApplicationPtr m_ipApp;)来引用到一个应用程序。注意到没有,这儿的接口变量定义和VB的有什么不同,除了本身的语法。就是接口多了‘Ptr’。因此,在VC中如何使用AO的对象你现在应该猜到一些了吧。
6. 下面的工作就是实现接口了。看看Iworld接口中都有哪些东西,哦,这个OnClick()应该是我们想要做些事情的地方了。
// STDMETHODIMP CZoomIn::OnClick(){
IDocumentPtr ipDoc;
m_ipApp->get_Document(&ipDoc);
IMxDocumentPtr ipMxDoc(ipDoc);
IMapPtr ipmap;
ipMxDoc->get_FocusMap(&ipmap)
ipmap->put_Name(_bstr_t("Hello,world"));
…………
::MessageBox(NULL,_T("Hello World!"),_T("Wellcom AO"), MB_OK);
return S_OK;
//}
7.编译连接工程;
8.在 ArcMap中注册后就可以将该按钮直接拖放到ArcMap中来使用了。(当你点击时,会弹出当前地图被修改后的名称----“Hello,world”。
4.4AO程序实现的一般过程
不管是用VB还是VC或是其它,要做的第一步就是在集成环境因入AO对象库(Esricore.olb),剩下的工作在接口中实现你要做的事情。关于如何进入VB和VC开发的完整代码及说明,请参阅ArcObject Developer Help。
第五章 AO高级通用组件
可能是有感于独立AO应用程序开发群的迅速扩大,ESRI在其最新的ArcGIS8.2版本中不但继续提供对MapControl控件的开发支持,而且新增了一个PageLayoutControl控件,这对于有制图应用的开发者来说无疑带来了福音。许多时候可能会对组件和控件有些糊涂,其实Active X并不能代表整个COM,它只是COM对象的封装技术,由于COM对象使用的复杂性,因此才会创建框架(如Active X控件)来简化它。所以这两个控件也可称为AO高级通用组件,它由AO基础组件构造而成,面向通用功能,简化了用户开发过程,组件之间的协同控制消息都被封装起来。这级组件经过封装后,使二次开发更为简单。如一个简单的AO应用系统,若用基础AO组件对象开发,需要编写不少的代码,而利用高级通用组件,只需几句代码就够了。
5.1MapControl控件
MapControl控件提供了类似ArcMap中的数据视图(Data View)的窗口,通过它你可完成以下甚至更多功能:
显示图层地图。
放大,缩小,漫游。
生成图形元素,如点,线,圆,多边形。
说明注记
识别地图上被选中的元素,进行空间或属性查询。
标注地图元素。
总之在ArcMap中能能够完成的大部分任务,通过MapControl控件也可以完成。通过设置MapControl General, Layers, Map 属性,你甚至不需要写一行代码可以获得一些GIS功能。关于MapControl控件有许多完整的应用示例,存放在\\ArcObjects Developer Kit\Samples\Controls目录下。
5.2PageLayout控件
PageLayout控件提供了类似ArcMap中的版面视图的窗口,它有以下的属性、方法和事件:
• 管理控件的外观设置
• 管理控件的显示属性
• 管理页面属性
• 在控件中增加和查找元素
• 加载地图文档到控件
• 可以直接从资源管理器和ArcCatalog中拖放数据到控件中
• 打印页面设计.
至于它的功能嘛,ArcMap的Layout 视图能完成的工作,使用PageLayoutControl同样可以完成,象增加和设置图例、打印输出等许多功能。关于PageLayout控件有许多完整的应用示例,也存放在\\ArcObjects Developer Kit\Samples\Controls目录下。
5.3MapControl和MapObject的关系
确切地讲,MapControl和MapObject控件没有直接的联系。首先,MapControl控件是AO的一部分,至少到目前为止它还不是一个独立的产品,而MapObject是ESRI的一个独立的低端应用产品。第二,MapControl比MapObject功能要强大许多和完善许多,MapObject产品的定位就是提供一些基本的地图功能,高级的功能这得完全靠开发者自己去实现,而依托强大的AO组件库MapControl可以实现许多高级的GIS分析及应用。