二次开发培训教程.doc
前 言 MAPGIS是武汉中地信息工程有限公司研制的具有自主版权的大型基础地理信息系统平台。它是一个集当代最先进的图形、图像、地质、地理、遥感、测绘、人工智能、计算机科学于一体的大型智能软件系统,是集数字制图、数据库管理及空间分析为一体的空间信息系统,是进行现代化管理和决策的先进工具。MAPGIS连续四年在全国GIS测评中名列第一,并成为唯一连续四年获得国家科技部向社会推荐的国产GIS软件平台。 中地软件丛书之MAPGIS二次开发培训教程是根据最新推出的MAPGIS软件平台编写而成,主要介绍进行MAPGIS二次开发必须具备的基础知识、主流开发工具以及MAPGIS系统的基本概念、结构体系和操作方法。该教程分为三个部分,共十一讲。其中 第一部分(即第一讲的内容)介绍Windows编程的概念。包括类与数据封装、继承、重载、虚拟函数与多态性以及内存管理。该部分为可视化编程的基础,有可视化编程经验的读者可以略过此讲,直接进入下一部分的学习。 第二部分(即第二讲的内容)编程工具VC。对于在VC这样一个编程环境中开发应用程序所应熟悉的概念,术语和最基本的框架、构件实现过程等知识做了一个简明扼要的介绍。已掌握一定VC编程基础知识的读者可以略过该部分。 第三部分(即第三讲至第十一讲的内容)详细讲述了地理信息系统的基本概念(包括GIS原理概述、空间数据类型、空间数据库、空间数据结构与数据管理等内容);MAPGIS的基本概念和体系结构(简要描述了MAPGIS二次开发的基本概念、术语、工作区、空间实体及其数据、C类组织和开发环境介绍的内容);MAPGIS空间数据存取和属性编辑(包括工作区、空间实体和属性的操作及其网络介绍);图形显示输出及窗口操作、图形编辑、类库和控件开发;矢量空间分析和属性查询;投影变换、图框生成和工程管理;图库管理和查询系统(包括基于图库的应用程序开发、MAPGIS图库介绍、开发的一般步骤以及结合图库显示说明图库主要函数的功能等方面的内容)以及图象分析与处理。这一部分为本教程的主要部分,能使大家从了解到熟练掌握这个部分的内容也是我们编制本书的主要目的,同时它还可被作为MAPGIS二次开发过程中的参考来使用。 参加本书编写的人员主要是本系统的软件开发人员以及长期从事MAPCAD和MAPGIS培训的教师。由于时间仓促,书中难免存在错误和不当之处,敬请广大用户及读者提出宝贵意见和建议,以利改进。 中地软件丛书编委会 2001年10月 目 录 第一讲 基于WINDOWS编程的基础知识1 1.1引言1 1.2类与数据封装1 1.3继承2 1.4重载4 1.5虚拟函数与多态性5 第二讲 编程工具VC8 2.1熟悉VC开发环境8 2.2消息与命令8 2.3文档、视结构10 2.4图形设备接口11 2.5对话框和控件12 2.6编程规范13 第三讲 地理信息系统基本概念15 3.1 GIS原理概述15 3.2 GIS空间数据类型17 3.3 GIS数据管理18 3.4空间分析20 3.5地理信息系统发展20 第四讲 MAPGIS的基本概念和体系结构22 4.1 MAPGIS二次开发的基本概念22 4.2 MAPGIS基本术语23 4.3 MAPGIS的数据管理(工作区)25 4.4 MAPGIS的空间实体及其数据组织27 4.5 MAPGIS的C类组织29 4.6 MAPGIS的VC开发环境介绍30 第五讲 MAPGIS空间数据存取和属性编辑32 5.1工作区操作32 5.2空间实体操作34 5.3属性(属性结构)操作37 5.4网络介绍44 第六讲 图形显示输出及窗口处理45 6.1图形显示输出45 6.2窗口处理49 6.3类库开发中的图形显示和窗口处理51 第七讲 图形编辑、类库和控件开发53 7.1图形编辑开发概要53 7.2图形编辑API函数开发53 7.3 MAPGIS类库开发54 7.4 MAPGIS控件开发60 第八讲 矢量空间分析和属性查询66 8.1矢量空间分析66 8.2属性查询检索71 第九讲 投影变换和图框生成73 9.1投影变换projdll.h、cordcvt.h73 9.2图框生成frmdll32.h83 第十讲 图库管理和工程管理91 10.1 MAPGIS图库简介91 10.2基于图库的应用程序的开发92 10.3结合图库的显示说明图库中主要函数的功能92 10.4工程管理prj_disp.h和map_prj.h96 第十一讲 MAPGIS图象处理和分析101 11.1遥感图象处理的基本知识101 11.2处理方法101 11.3主要API 介绍99 11.4组件介绍107 11.5在VC中的开发过程(结合示例程序讲解)108 11.6示例程序说明109 附 录 MAPGIS 二次开发问题集锦110 1.属性和属性结构110 2.空间实体操作问题123 3.显示、编辑问题124 4.空间分析问题131 5.数字高程模型131 6.安装问题134 7.工程问题135 8.输出问题136 9.其它138 第一讲 基于WINDOWS编程的基础知识 第一讲 基于WINDOWS编程的基础知识 1.1引言 1.1.1 过程化procedural programming 程序被认为是在一个数据集合上进行的一系列操作。 1.1.2 结构化structured programming 主要思想是功能分解并逐步求精。 1.1.3 面向对象的程序设计object_oriented programming 实质是把数据和处理这些数据的过程合并为一个单独的“对象”一个具有确定特性的自完备的实体。 1.1.4 面向对象程序设计的特征 1) 封装 2) 继承 3) 多态 1.2类与数据封装 1.2.1 什么是类 简单的说,类就是一种用户定义的数据类型,跟结构类似;并且,类具有自己的成员变量和成员函数(方法),通过它们可以对类自身进行操作。如汽车可以看作是发动机、车轮、座椅等诸如此类的集合。也可以从功能的角度来研究,譬如,能移动,加速,减速,刹车等。 例如 class CMyClass1 { protected CMyClass1; public virtual CMyClass1; } 1.2.2 封装(encapsulation) 定义指能够把一个实体的信息、功能、响应都装入一个单独的对象中的特性。封装的优点如下 1 封装允许类的客户不必关心类的工作机理就可以使用它。就象驾驶员不必了解发动机的工作原理就可以驾驶汽车一样,类的客户在使用一个类时也不必了解它是如何工作的,而只需了解它的功能即可。 2 所有对数据的访问和操作都必须通过特定的方法,否则便无法使用,从而达到数据隐藏的目的。 1.2.3 对象 对象就是类的实例。类与对象的关系就如类型和变量的关系,所有对类的操作都必须通过对象来实现。当一个类定义了多个对象时,每个对象拥有各自的成员数据。 1.2.4 类的三种成员类型 1 私有成员private缺省情况下,一个类中的所有成员都是私有的。私有成员只能被类本身的成员函数访问。并且不具有继承性。 2 公有成员public公有成员可以被类成员函数和外部函数使用。 3 保护成员protected类的保护成员能被类及其派生类的成员函数和友员函数使用,具有继承性。 1.2.5 构造函数与析构函数 1)构造函数 a. 是特殊的成员函数;在创建对象时首先由系统自动调用。它的作用是为新创建的对象分配空间,或为该对象的成员变量赋值等; b. 构造函数名必须与其类名称完全相同,并且不允许有返回值。 2)析构函数 a. 析构函数是构造函数的逆操作; b. 析构函数在类名之前加来命名,它不允许有返回值,也不允许带参数,并且一个类只能有一个析构函数。 1.3继承 1.3.1 传统程序设计的缺点 增加功能对程序所作的修改工作量非常大。 1.3.2 继承的优点 继承的方法允许在不改动原程序的基础上对其进行扩充,这样使得原功能得以保存,而新功能也得以扩展。这有利于减少重复编码,提高软件的开发效率。 1.3.3 基类与派生类 1)一个类可以继承其它类的成员,被继承的类叫基类或父类;继承类叫派生类或子类 2)派生类不但拥有自己的成员变量和成员函数,还拥有父类的成员变量和成员函数。 1.3.4 类的保护成员protected 前面介绍了类的私有成员只能被类的成员函数和友员函数使用;类的保护成员能被类及其派生类的成员函数和友员函数使用。也就是说,类的保护成员具有继承性,而类的私有成员不具有继承性。 1.3.5 公用基类和私有基类 1)公用基类中的所有public成员在派生类中仍是public成员,所有protected成员在派生类中仍是protected成员。 2)私有基类中的public成员和protected成员在派生类中均变成private成员。 1.3.6 多重继承 1)多重继承的定义方法 例子 class A { public int i; void func1; }; class B { public int i; void func1; }; class C public A,B { void Show }; 缺省情况下基类被定义为 private;因此基类B为私有基类。 2)继承的不确定性 例子 class Cpublic A,B { void Show { j i*i; func1; } }; 由于基类A和B中同时拥有数据成员i和成员函数func1,类C引用基类的成员时,系统无法分辨是调用哪一基类的成员而发生错误; 3)解决多重继承的不确定性 使用域操作符指明要调用的基类,即可解决不确定性问题。 class Cpublic A,B { int j; void Show { j Ai*Bi; Afunc1; } }; 1.3.7 多层继承 定义所谓多层继承指的是从一个类派生出另一个类,然后以派生类作为基类,派生出另一个类,直到最后生成的派生类满足需要为止(见MSDN中的Hierarchy Chart)。 1.3.8 派生类的构造函数与析构函数 在继承关系下,派生类的构造函数负责调用基类的构造函数来设置基类数据成员值。 例 class base {//基类 public int i; baseint j {//构造函数 i j; } }; class derivedpublic base {//派生类 public double f; derivedint, double; }; derivedderivedint k, double lbasek {//派生类构造函数 f l; } 1.3.9 构造函数的调用顺序 1 在定义派生类对象时,系统首先调用基类的构造函数,然后调用派生类的构造函数;在上例中,derived类首先调用base类的构造函数,然后调用自身的构造函数。 2 析构函数的调用顺序与构造函数的调用顺序相反。 1.4重载 1.4.1函数重载 1)如果函数有相同的名称和返回值,而有不同的参数个数或参数类型,则这些函数就是重载函数。 2)派生类继承了基类的某一函数,并且又自定义了一个同名函数,有相同的返回值,不同的参数类型或参数个数。这种情况不属于重载。因为它们属于不同的域。 3)例 class base { void funcint i { } void funcdouble f { } void funcdouble f, long q { } }; 1.4.2 操作符重载 重载操作符的定义返回值类型 operator op 参数表;其中,op为重载操作符,它必须是VC中所定义的运算符。然后像定义函数一样定义重载操作符函数。 例子 class person { int age; void operator ; }; void personoperator { age; } 1.5虚拟函数与多态性 多态性是面向对象程序设计的精髓之所在,也是C中最难理解和掌握的部分。在C中,多态性是建立在虚拟函数基础上的,虚拟函数的使用使类的成员函数表现出多态性。 1.5.1虚拟函数 1)函数的定义在定义类时在其成员函数前加上关键字virtual; 2)如果基类中成员函数定义为虚函数,则派生类中与其定义完全相同的成员函数,编译器自动将其视为虚函数; 3)只有类的成员函数才能定义为虚函数。 4)虚拟成员函数的存取要看首次定义它的类中,该函数是public还是private。 例 class Insect { virtual bool CanFly; }; bool Insect CanFly { return FALSE; } class Butterflypublic Insect { bool CanFly; }; bool Butterfly CanFly { return TRUE; } 1.5.2 虚函数的调用 1) 根据对象的不同而去调用不同类的虚拟函数 2) 可以使用基类对象调用派生类对象,即将派生类对象或指针赋值给基类对象或指针。 3) 反方向的赋值(将基类的对象或指针赋给派生类的对象或指针)是危险的。 例 bool rtn; Insectinc1,*pInc; Butterfly btfly; pInc //pInc指针指向Insect对象 rtn pInc-CanFly;//返回FALSE pInc //pInc指针指向Butterfly对象 rtn pInc-CanFly;//返回TRUE 1.5.3 虚拟函数与重载函数的区别 1)形式上,重载函数要求有相同的返回值类型和函数名,并有不同的参数序列;而虚拟函数要求三者完全相同。 2)重载函数可以是成员函数或非成员函数;而虚拟函数必须是成员函数。 3)调用方法上,重载函数根据所传递的参数序列的差别作为调用的依据;而虚拟函数则根据调用对象的不同而去调用不同类的函数。 4)虚拟函数在运行时表现出多态功能;而重载函数不具有这一功能。 1.5.4纯虚函数 定义virtual type funcnameparameter0; C中有时设计基类就是为了被继承,而基类中的虚拟函数不做任何工作,这种情况下可以将基类中的虚拟函数定义为纯虚函数。包含纯需函数的类叫抽象类。抽象类不能定义对象,但可以定义指向它的指针。 习题 1.1什么是类 1.2理解封装、继承和多态。 第二讲 编程工具VC 2.1熟悉VC开发环境 2.1.1 VC向导提供的帮助 以前Windows编程需要程序员编写大量的框架代码,这对初学者来说简直就是一个噩梦;并且这些框架代码基本相同,因此Microsoft提供了向导AppWizard帮助生成框架代码,这极大的方便了我们编写程序。 2.1.2 VC向导可以生成的工程类型 ATL COM AppWizard CustomAppWizard DatabaseProject ISAPI Extension Wizard Makefile MFC ActiveX ControWizard MFC AppWizard DLL MFC Database Wizard Win32 Application Win32 Console Application Win32 DLL Win32 Static Library 2.1.3 建立第一个应用程序 使用向导AppWizard生成典型的应用程序基于多文档的可执行程序。 2.1.4 如何获取帮助 Microsoft的MSDN提供了编程所需的绝大部分信息,使用F1键可以打开MSDN帮助。 2.2消息与命令 2.2.1 消息 消息是Windows编程不同于其它编程方式的地方,如DOS环境下编程。消息就是操作系统通知应用程序某事已发生的一种方式,如用户已输入、已单击或移动鼠标、打印机已空暇等。 2.2.2 消息传递 1 尽管操作系统用整数来引用消息,但所有消息都通过它们的名字来引用。一个巨大的define语句将消息名同数值联系起来。不同消息由操作系统或应用程序的不同部分处理。如,当用户在窗口上移动鼠标时,窗口得到一个WM_MOUSEMOVE消息,它几乎全部传送给操作系统去处理。 2)MFC允许程序员忽略底层消息,并使得在单独类级别上声明每个类处理哪些消息更容易。 2.2.3 消息循环 - 8 - 第二讲 编程工具VC 1)任何windows 程序的核心是消息循环,这通常包含 在WinMain 例程中。 2)MFC 通过消息映射来保持消息处理函数与消息处理信息的一致。 2.2.4 消息映射 消息映射是进行windows 编程的一部分MFC 方法,用来代替编写向用户的WinProc 发送消息的WinMain 函数,及编写检查消息类型的WinProc 函数。用户只需编写处理消息的函数,并且在用户的类中增加一个消息映射即可,其它一切由MFC 处理。 2.2.5 消息映射宏 在类声明的结尾部分,使用宏 DECLARE_MESSAGE_MAP来声明在类定义部分需要消息映射。在*.CPP文件中使用宏 BEGIN_MESSAGE_MAP和END_MESSAGE_MAP来声明消息映射,在两个宏之间声明消息的映射函数。 2.2.6 常用消息映射宏 ON_COMMAND 用于将特定命令的处理委派给类的一个成员函数。 ON_MESSAGE 用于将用户自定义消息的处理委派给类的一个成员函数。 2.2.7 使用ClassWizard帮助用户捕获消息 1)带标签的ClassWizard对话框 通过选择View,Classwizard或按CtrlW可以显示主Classwizard对话框。在对话框的顶部有两个下拉列表框,一个用于提示正在处理的工程文件(本例是),另外一个用于提示哪一个类拥有正在进行编辑的消息映射。在这两个组合框下面是一个列表框。左边的框列出了类本身和用户局面可以产生的所有命令。右边的框列出了这个类可以捕获的所有Windows消息,也列出了许多捕获常用消息的虚函数。 在这些框的右边是一些按钮,它们的作用分别是向工程文件增加新类、向类中增加一函数以捕获被高亮显示的消息、删除正在捕获消息的函数,以及为捕获高亮显示消息的函数打开源代码口通常,用户选中一个类,选中一个消息,并单击Add Function来捕获消息。下面就是Add Function按钮所做的事情 a 将一个骨架函数添加到应用程序源文件的末尾。 b 在源文件的消息映射中增加一个入口。 c 在包含文件中的消息映射中增加一个入口。 d 更新对话框中的消息和成员函数列表。 2)添加Windows消息处理函数对话框 还有另外一种捕获消息的方法。用户可以右击ClassView中的类名,然后从出现的快捷菜单中选择Add Windows Message Handler。这时将出现如下图所示的对话框。 2.2.8 命令 命令是一种特殊的消息类型。用户在任何时候选择一个菜单项,单击一个按钮或告诉系统做什么,windows 都将产生一个命令。 ClassWizard可帮助用户捕获命令。 运行界面与消息捕获类似。 命令消息都通过被选择的菜单或被单击的按钮的资源ID与相应的处理函数进行关联。只有从CWnd派生的对象可以接收消息。每个资源ID仅关联两个消息COMMAND和UPDATE_COMMAND_UI。第一个消息允许增加处理用户选中菜单选项或单击按钮的函数一一也就是说,捕获命令。第二个使用户可增加一个设置菜单项、按钮或者其他控件的状态的函数,就像操作系统即将显示它们一样一一也就是说,更新命令。单击Add Function来增加一个捕获或更新包含额外步骤的命令。 2.3文档、视结构 2.3.1 简介 MFC的文档/视图结构把应用程序的数据从用户实际浏览和操纵数据的方法中分离开来。简单的说,文档对象负责存储、加载和保存数据,而视图对象允许用户在屏幕上查看数据,并用适合于应用程序的方法编辑数据。 2.3.2 了解文档 CDocument类 一个文档代表了一个数据集合,典型情况下一个文档由用户通过File Open命令打开并通过 File Save命令保存。用户通过与文档关联的CView对象操作文档。一个文档可以有多个视图关联。 2.3.3 了解视图 视图是显示存储在文档对象中的数据,并允许用户修改这些数据。视图对象保持了一个文档对象的指针。为了显示和修改数据,视图对象可用这个指针访问文档的成员变量。一个视图对象只能与一个文档对象关联。调用OnUpdate 函数可以更新一个视图。所有的屏幕显示操作可在从CView继承的派生类的OnDraw成员函数中完成。 CView类的派生类 CCtrlView 实现常用控件的视图 CEditView 提供基本的文本编辑功能 CRichEditView 提供复杂的文本编辑功能 CView 通过使用对话框资源实现窗体式窗口 CRecordView 提供了显示数据库记录的功能 CDaoRecordView 一般与DAO数据库类一起使用,其余与CRecordView相同。 CScrollView 提供滚动功能 CListView 在窗口中显示CListView控件 CTreeView 在窗口中显示CTreeView控件 2.4图形设备接口 2.4.1 理解设备环境 1)户能够显示任何形式的数据,因为窗口中显示的所有东西,不论是文字、表格、位图或是其它任何类型的数据,都是以图形方式显示的。 2)MFC通过将windows的GDI函数和对象封装到其设备环境(DC)类中来帮助用户显示数据。 3)一个设备环境(DC)就是一个数据结构,它对窗口的绘制表面的属性保持跟踪。这些属性包括当前选择的画笔、画刷和用来在屏幕上绘制的字体。一个DC一次只能有一种画笔一种画刷和一种字体。设备环境对象封装了画线、写文本等API函数,所有的画图操作都通过DC对象进行。 4)DC帮助Windows实现了设备无关性。DC能用来输出到屏幕、打印机和元文件。 什么是元文件metafile 元文件就是由一系列可变长度结构组成的数组,图片以设备无关的格式存储在结构中。当元文件的记录被转换成设备命令并被合适的设备处理时,元文件被显示。 5)CDC类。CDC就是设备环境对象类。CDC对象提供了操作DC的成员函数。可以通过CDC对象类的成员函数来进行所有的绘图操作。 6)CPaintDC类 a. CPaintDC 类继承CDC 类; b. CPaintDC 类的构造函数自动调用OnPaint 函数,接着就可以在DC 中绘图;类的析构函数自动调用EndPaint 函数。 c. BeginPaint 函数准备绘图的窗口;EndPaint 函数表明结束窗口的绘图。 d.在视图类的OnDraw 函数中,CPaintDC已经由系统准备好,可以直接在OnDraw 中绘图。并且CPaintDC由系统自动释放。 7)CClientDC类 CClientDC对象封装了所有对Windows客户区DC的操作。CClientDC通过调用GetDC函数得到,通过ReleaseDC函数释放。 8)CWindowDC类 CWindowDC对象封装了对整个window窗口,包括框架的操作。 9)CMetaFileDC类 CMetaFileDC对象封装了对一个Windows 元文件的绘图操作。但是必须自己调用OnPrepareDC函数,来准备设备环境。 2.4.2 图形对象Graphic Object Windows 提供了多种在DC 中使用的图形对象类。这些类与Windows GDI的句柄类型相对应。 图形对象类 Windows 句柄类型 CPen HPEN CBrushHBRUSH CFont HFONT CBitmap HBITMAP CPalette HPALETTE CRgn HRGN 使用图形对象的一般步骤 1)定义图形对象,使用图形对象类的Create函数如CreatePen创建对应的对象。 2)将创建的图形对象选进当前设备环境(DC)中,并保存旧的图形对象。 3)完成使用当前图形对象后,将原图形对象选回DC中。 4)保证分配的图形对象在结束使用后被删除。 注意如果要反复的使用一个图形对象,可以只申请一次,然后在需要的时候将其选入DC中。但是必须确保在不再需要使用图形对象的时候,删除它。 2.5对话框和控件 2.5.1 对话框 Windows应用程序可能有多个对话框,对于每一个对话框,必须开发两个实体对话框资源和对话框类。对话框资源用于定义在屏幕上显示的对话框和它的控件的大小和位置等信息。对话框类是对话框和它的控件的对应代码。用户可以用资源编辑器建立对话框资源,向其中增加控件和对它们进行调整。对话框及在对话框上的控件都必须有一个用于标识的ID。ClassWizard帮助用户建立一个对话框类,通常由MFC类CDialog派生而来,并将资源和类相连。 通常对话框上的每一个控件对应类中的一个成员变量。要显示对话框,可调用类的成员函数。可以在显示对话框前为控件设置缺省值,或使用控件对应的成员变量设定控件值。使用ClassWizard中的Member Variables可以为对话框上的控件本身或控件值建立对应的类成员变量。 单击上图中的Add Variable按钮,将弹出如下图所示的Add Member Variable对话框。 在这个对话框的Category和Variable type下拉式组合框中可以选择控件对应成员变量的类型Value或Control类型,以及它们确切对应的类型。然后,在程序中就可以使用定义的变量来操纵控件了。 2.5.2 控件 1)基本控件 Windows常用控件 MFC对应的类 按钮控件 CButton 编辑框控件 Cedit 复选框控件 CCheck 列表框控件 CListBox 进度条控件Progress bar CProgressCtrl 滑块控件 CSliderCtrl 上下控件 CSpinButtonCtrl 图象列表image list CImageList 列表视图控件list view CListCtrl 树形控件tree view CTreeCtrl Rich Edit控件 CrichEditCtrl 2)添加自定义控件 在应用程序中可以添加一些自己生成的或由他人提供的控件。方法如下 首先,选择菜单project,Add To Project,Components And Controls,弹出对话框“Components And Control Galley”对话框,选择“Registered ActiveX Controls”。 然后,选择准备插入的控件(如“GisAttEdit Contro”),按Insert按钮,会在程序中生成控件对应的类。 接着,就可以像使用标准控件一样使用插入的控件了。 2.6编程规范 2.6.1 书写风格 大括号的对齐,锯齿状对齐、缩进;使用空白(空字符,空行)以增加可读性。 2.6.2 命名规范 匈牙利记法变量具有一个描述性的名字,如ClassName,名字用大写字母开始;如果变量是一多词名则每个单词词头需大写。然后,在描述性名称前,加上表示变量类型的字母如,nCount为一整型变量,bFlag为一Boolean型变量。 前缀 变量 注释 a Array b Boolean d Double h Handle I Integer “index into” l Long lp Long pointer to lpfn Long pointer to function m Member variable n Integer “number of” p Pointer to s String sz Zero terminated string u Unsigned integer C Class 2.6.3 注释规则 1)函数注释 函数开头必须注明函数功能、参数、返回值 2)变量注释 应说明变量的作用 3)其它注释 每个功能模块应加注释,如一个循环体、一个判断等都需要加注释。 习题 2.1建立一个基于多文档的应用程序,添加自己的菜单项,使用ClassVizard进行消息映射。 2.2在上题基础上,使用图形设备接口,在窗口上绘图。要求每按下一次鼠标左键,就以鼠标所点坐标为中心,画一个圆。 2.3建立一个基于对话框的应用程序。使用几个基本控件,如编辑框、按钮、组合框等,并生成对应的变量,然后,通过这些变量控制控件的值。 第三讲 地理信息系统基本概念 3.1 GIS原理概述 3.1.1 GIS概念 地理信息系统(GIS)是在计算机软硬件支持下,以采集、存贮、管理、检索、分析和描述空间物体的地理分布数据及与之相关的属性,并回答用户问题等为主要任务的技术系统。 3.1.2 GIS发展 1)起始发展阶段60年代 1963年由加拿大测量学家R.F.Tomlinson提出并建立的世界上第一个地理信息系统是加拿大地理信息系统CGIS。 1963年美国哈佛大学城市建筑和规划师Howard T.Fisher设计和建立了SYMAP系统软件。 1966年美国成立了城市和区域信息系统协会URISA,1968年国际地理联合会IGU设立了地理数据收集委员会CGDSP。 1969年,又建立起州信息系统国协会NASIS。 2)发展巩固阶段70年代 70年代,GIS朝实用方向发展。各国对GIS的研究均投入了大量人力、物力、财力。不同规模、不同专题的信息系统得到很大发展。从1970年到1976年美国地质调查局发展了50多个地理信息系统。GIS受到政府、商业和学校的普遍重视。 3)推广应用阶段80年代 80年代,GIS在全世界范围内全面推广应用,应用领域不断扩大,开始用于全球性的问题。开展GIS工作的国家更为广泛,国际合作日益加强。GIS软件开发具有突破性的进展,仅1989年市场上有报价的软件达70多个。代表性的有ARC/INFO(美国)、GENAMAP(澳大利亚)、SPANS(拿加大)、MAPINFO(美国)、MGE(美国)、System9(瑞士/美国)、ERDAS(美国)。 4)蓬勃发展阶段90年代以后 90年代,随着地理信息产生的建立和数字化信息产品在全世界的普及,GIA已成为确定性的产业,投入使用的GIS系统,每2~3年就翻一番,GIS市场的年增长率为35以上,从事GIS的厂家已超过300家。GIS已渗透到各行各业,涉及千家万户,成为人们生产、生活、学习和工作中不可缺少的工具和助手。 3.1.3 GIS组成 1)数据输入和检验 2)数据存储和管理 3)数据变换 4)数据输出和表示 5)用户接口 3.1.4 GIS功能 1)数据采集与输入 数据采集与输入,即在数据处理系统中将系统外部的原始数据传输给系统内部,并将这 - 16 - 第三讲 地理信息系统基本概念 些数据从外部格式转换为系统便于处理的内部格式的过程。主要有图形数据输入,如管网图输入;栅格数据输入,如遥感图像的输入;测量数据输入,如全球定位系统(GPS)数据的输入;属性数据输入,如数字和文字的输入。 2)数据编辑与更新 数据编辑主要包括图形编辑和属性编辑。属性编辑主要与数据库管理结合在一起完成,图形编辑主要包括拓扑关系建立、图形编辑、图形整饰、图幅拼接、图形变换、投影变换、误差校正等功能。数据更新即以新的数据项或记录来替换数据文件或数据库中相对应的数据项或记录,它是通过删除、修改、插入等一系列操作来实现的。 3)数据存贮与管理 属性数据管理一般直接利用商用关系数据库软件,如ORACLE、ACCESS、FoxBase、FoxPro等进行管理。空间数据管理是GIS数据管理的核心,各种图形或图像信息都以严密的逻辑结构存放在空间数据库中。 4)空间查询与分析 空间查询与分析是GIS核心,主要包括数据操作运算、数据查询检索与数据综合分析。包括矢量数据叠合、栅格数据迭加等操作、算术运算、关系运算、逻辑运算、函数运算等。综合分析主要包括信息量测、属性分析、统计分析、二维模型分析、三维模型分析、多要素综合分析等。 5)数据显示与输出 数据显示是中间处理过程和最终结果的屏幕显示,通常以人机交互方式来选择显示的对象与形式,对于图形数据根据要素的信息量和密集程度,可选择放大或缩小显示。GIS不仅可以输出全要素地图,也可以根据用户需要,分层输出各种专题图、各类统计图、图表及数据等。 3.1.5 GIS应用 1)资源清查 2)城乡规划 3)灾害监测 4)土地调查 5)环境管理 6)城市管网 7)作战指挥 8)宏观决策 3.2 GIS空间数据类型 3.2.1栅格数据数据结构 将工作区域的平面表象按一定分解力作行和列的规则划分,形成许多格网,每个网格单元称为象素,栅格数据结构实际上就是象元阵列,即象元按矩阵形式的集合,栅格中的每个象元是栅格数据中最基本的信息存储单元,其坐标位置可以用行号和列号确定。 3.2.2 矢量数据数据结构 矢量数据就是代表地图图形的各离散点平面坐标(x,y)的有序集合。 拓扑关系是指网结构元素结点、弧段、面域之间的空间关系,主要表现为下列三种关系拓扑邻接关系、拓扑关联关系、拓扑包含关系 3.2.3 矢栅一体化数据结构 用填满线性目标路径和充满面状目标空间的表达方法作为一体化数据结构的基础,每个线性目标除记录原始取样点外,还记录路径所通过的栅