二次开发初级培训班培训讲义

更新时间:2024-06-18 09:12:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

第一讲 基于WINDOWS编程的基础知识

1.引言

1.1 过程化(procedural programming):程序被认为是在一个数据集合上进行的一系列操作。

1.2 结构化(structured programming):主要思想是:功能分解并逐步求精。 1.3 面向对象的程序设计(object_oriented programming)

实质是把数据和处理这些数据的过程合并为一个单独的“对象”――一个具有确定特性的自完备的实体。

1.4 对象的程序设计的特征

1) 自完备(self_contained):能够完全实现一些严格定义的功能。 2) 封装 3) 继承 4) 多态

2. 类与数据封装

2.1 什么是类?

简单的说,类就是一种用户定义的数据类型,跟结构类似;并且,类具有自己的成员变量和成员函数(方法),通过它们可以对类自身进行操作。 如:汽车可以看作是发动机、车轮、座椅等诸如此类的集合。也可以从功能的角度来研究,譬如,能移动,加速,减速,刹车等。

定义(例子)VC++中讲解

2.2 封装(encapsulation)

定义:指能够把一个实体的信息、功能、响应都装入一个单独的对象中的特性。

封装的优点:

◆ 封装允许类的客户不必关心类的工作机理就可以使用它。就象驾驶员不必了解发动机的工作原理就可以驾驶汽车一样,类的客户在使用一个类时也不必了解它是如何工作的,而只需了解它的功能即可。

◆ 所有对数据的访问和操作都必须通过特定的方法,否则便无法使用,从而达到数据隐藏的目的。

2.3 对象

对象就是类的一个实例。类与对象的关系就如类型和变量的关系,所有对类的操作都必须通过对象来实现。当一个类定义了多个对象时,每个对象拥有各自的成员数据。 2.4 类的三种成员类型

◆ 私有成员(private):缺省情况下,一个类中的所有成员都是私有的。私有成员只能被类本身的成员函数访问。并且不具有继承性。

◆ 公有成员(public):公有成员可以被类成员函数和外部函数使用。

◆ 保护成员(protected):在介绍继承时再介绍。

2.5 构造函数与析构函数

1)构造函数

◆ 是特殊的成员函数;在创建对象时首先由系统自动调用。它的作用是为新创建的对象分配空间,或为该对象的数据成员赋值等。

◆ 构造函数的名称必须与其类名称完全相同,并且不允许有返回值。

2)析构函数

◆ 析构函数是构造函数的逆操作。

◆ 析构函数在类名之前加~来命名,它不允许有返回值,也不允许带参数,并且一个类只能有一个析构函数。 2.6 简单介绍

1)const 用法

const 变量: const int i = 5; i = 10; // Error i++; // Error const 型成员函数

Void SomeFunction() const ; 此方法不能改变类中的任何成员。当成员函数不改变对象的属性时,就应当把它说明为CONST 型函数。这可以使编译程序帮助查错,比程序员亲自查错要快得多,而且开销更少。[错误的类型:语法错、编译错、链接错、运行错、逻辑错] 2)类静态成员

静态成员变量被一个类所有的实例所共享。静态变量使用固定地址存放,而不使用对象。

定义:在变量或函数前加关键字static即可。 例:class counter {

static long t1; ??

static GetValue1() {

return t1; }

}

它属于类而不属于对象。调用时,使用类范围运算符;

counter::t1 = 1;

counter::GetValue1();

静态成员函数没有this指针,因此不能被说明为const类型。以因为其它的函数在访问成员变量时需要使用this指针,所以静态成员函数不能访问任何非静态成员变量。

3)类的友员

使用友员函数或友员类的成员函数可以访问类的私有成员。但友员函数不属于类的成员函数。

友员函数的定义:

在类的任何地方定义,只须在函数前加上关键字friend即可;

例:class FriendFun

{ friend void Display(FriendFun*);

char *name; int age; public: FriendFun(char* str, int i) { name = str;

age = i;

}

}

void Display(FriendFun * a)

{ cout << “The friend ” << a->name << “is”<< a->age

}

<<“years old”<

void main() { FriendFun dd(“Frank”,45);

Display(&dd);

}

友员类

◆ 友员类的成员函数可以象类的友员函数一样访问该类的所有成员;

◆ 友员类不一定是相互的;即类A是类B的友员类,但类B不一定是类A的友员类; ◆ 友员类的定义与友员函数的定义类似;

3. 继承

3.1 传统程序设计的缺点:

增加功能对程序所作的修改工作量非常大

3.2 继承的优点:

继承的方法允许在不改动原程序的基础上对其进行扩充,这样使得原功能得以保存,而新功能也得以扩展。这有利于减少重复编码,提高软件的开发效率。

3.3 基类与派生类

1)一个类可以继承其它类的成员,被继承的类叫基类或父类;继承类叫派生类或子类 2)派生类不但拥有自己的数据成员和成员函数,还可以拥有父类的数据成员和成员函数。

3.4 类的保护成员(protected)

前面介绍了类的私有成员只能被类的成员函数和友员函数使用;类的保护成员能被类及其派生类的成员函数和友员函数使用。也就是说,类的保护成员具有继承性,而类的私有成员不具有继承性。

3.5 公用基类和私有基类

1)公用基类中的所有public成员在派生类中仍是public成员,所有protected成员在派生类中仍是protected成员。

2)私有基类中的public成员和protected成员在派生类中均变成private成员。 友员函数不能被继承。 3.6 多重继承

1)多重继承的定义方法 例子

Class A(){?int i; void func1();?} Class B(){?int i; void func1();?} Class C():public A,B {?void Show()?} 缺省情况下基类被定义为 private; 2)继承的不确定性 例子:

Class C():public A,B { ?

void Show() { j = i*i; func1();} ? }

3)解决多重继承的不确定性:

◆ 由于基类A和B中同时拥有数据成员i和成员函数func1,类C引用基类的成员时,系统无法分辨是调用哪一基类的成员而发生错误;

◆ 使用域操作符指明要调用的基类,即可解决不确定性问题。 Class C():public A,B { ?

int j;

void Show() {

j = A::i*B::i; A::func1(); } ?

}

3.7 多层继承

定义:所谓多层继承指的是从一个类派生出另一个类,然后以该派生类作为基类,派生出另一个类,直到最后生成的派生类满足需要为止。

◆ 见MSDN中的Hierarchy Chart

3.8 派生类的构造函数与析构函数

在继承关系下,派生类的构造函数必须负责调用基类的构造函数来设置基类数据成员值。

例子

class base { ? public:

int i; base(int j) {i = j;} ? }

class derived:public base { ?

public: double f;

derive(int, double); ?

}

derive::derive(int k, double l):base(k) {

? f = l; ? }

3.9 构造函数的调用顺序

◆ 在定义派生类对象时,系统首先调用基类的构造函数,然后调用派生类的构造函数。

◆ 析构函数的调用顺序与构造函数的调用顺序相反。

4. 重载

4.1 函数重载

1)如果函数有相同的名称和返回值,而有不同的参数个数或参数类型,则这些函数就是重载函数。

2)派生类继承了基类的某一函数,并且又自定义了一个同名函数,有相同的返回值,不同的参数类型或参数个数。这种情况不属于重载。因为它们属于不同的域。

3)例: class base { ?

void func(int i); void func(double f); void func(char ch); ? }

class derive:public base { ?

void func(float flt); ? }

4.2 操作符重载

◆ 重载操作符的定义

◆ 返回值类型 operator op (参数表);

◆ 其中,op为重载操作符,它必须是VC++中所定义的运算符。然后象定义函数一样定义重载操作符函数。

例子:

Class person {

int age; void operator ++(); }

Void person::operator++() { age++; }

5. 虚拟函数与多态性

多态性是面向对象程序设计的精髓之所在,也是C++中最难理解和掌握的部分。在C++

中,多态性是建立在虚拟函数基础上的,虚拟函数的使用使类的成员函数表现出多态性。 5.1虚拟函数

1)函数的定义:在定义类时在其成员函数前加上关键字virtual;

2)如果基类中成员函数定义为虚函数,则派生类中与其定义完全相同的成员函数,编译器自动将其视为虚函数;

3)有类的成员函数才能定义为虚函数。

例:

class Insect { ??

virtual bool CanFly(); ?? }

bool Insect :: CanFly() {

return FALSE; }

class Butterfly:public insect { ??

Bool CanFly(); ??

}

bool Butterfly :: CanFly() {

return TRUE;

}

5.2 虚函数的调用

1)根据对象的不同而去调用不同类的虚拟函数 2)可以使用基类对象调用派生类对象,即将派生类对象或指针赋值该基类对象或指针。 3)反方向的赋值(将基类的对象或指针赋给派生类的对象或指针)是危险的。

例: bool

rtn;

Insect inc1,*pInc; Butterfly btfly; pInc = &inc1;

rtn = pInc->CanFly(); pInc = &btfly;

rtn = pInc->CanFly(); 5.3 虚拟函数与重载函数的区别

1)形式上,重载函数要求有相同的返回值类型和函数名,并有不同的参数序列;而虚拟函数要求三者完全相同。

2)重载函数可以是成员函数或非成员函数;而虚拟函数必须是成员函数。

3)调用方法上,重载函数根据所传递的参数序列的差别作为调用的依据;而虚拟函数则根据调用对象的不同而去调用不同类的函数。

4)虚拟函数在运行时表现出多态功能;而重载函数不具有这一功能。

5.4 虚拟函数的数据封装

虚拟成员函数的存取要看首次定义它的类中,该函数是public or private。 [纯虚函数]

定义:virtual type funcname(parameter)=0;

C++中有时设计基类就是为了被继承,而基类中的虚拟函数不做任何工作,这种情况下可以将基类中的虚拟函数定义为纯虚函数。包含纯需函数的类叫抽象类。抽象类不能定义对象,但可以定义一指向它的指针。 5.5虚拟基类

虚拟基类的定义,及解决的问题 例:

class B : virtual public A; class C : virtual public A;

class D : public B, public C; 5.6 虚拟基类的构造函数调用

在含虚拟基类的多层继承关系中,虚拟基类的构造函数调用由最远的派生类负责。

6. 内存管理

6.1 指针

1)采用安全的编程风格,对指针进行初始化。

2)NEW(调用构造函数)和 DELETE(会调用析构函数)

3)每次使用关键字NEW申请分配内存时,必须检查并确认返回的指针不为空。 [堆中] 4)当使用DELETE删除一个指针时,实际上是释放它所指向的内存空间。这相当于把此指针指向的内存空间交还给自由存储区。而这个指针本身还存在,可以再次对它赋值。

[注意]:当对一个指针使用DELETE时,它所指向的内存被释放。如果再次对它使用DELETE,有可能使程序崩溃。所以,当用DELETE删除一个指针后,应把它置为0(空指针)。而删除一个空指针是安全的。

6.2 内存泄露的原因

1)调用new操作符在堆上分配了一段内存,而没有调用delete操作符删除它;

2)改变了保存在一个变量中的指针的值,因而没能删除指针所指向的内存区;

3)带有指针类型成员变量的类,当new操作符分配了该指针,没有复制构造函数、赋 值运///////???

例: class A {

public: int *pi; } A::A() {

pi = new int(); *pi = 3; }

A first; A second; second = first;

6.3 栈和自由存储区(堆)

通常程序员要管理内存中以下五个区域 1)全局变量区

2)自由存储区 3)寄存器

4)代码区 5)栈

其中局部变量和函数形参位于栈中,代码位于代码区,全局变量在全局变量区,而寄存器被用于进行一些内部处理,如保存栈顶指针和指令指针等。所有剩余的内存空间都被作为自由存储区, 有时也被称为堆

第二讲 编程工具VC

1.熟悉VC开发环境

1.1 VC向导提供的帮助;

以前Windows编程需要程序员编写大量的框架代码,这对初学者来说简直就是一个噩梦;并且这些框架代码基本相同,因此Microsoft提供了向导AppWizard帮助生成框架代码,这极大的方便了我们编写程序

1.2 VC向导可以生成的工程类型

ATL COM AppWizard Custom AppWizard Database Project

ISAPI Extension Wizard Makefile

MFC ActiveX ControWizard MFC AppWizard (DLL) MFC Database Wizard Win32 Application Win32 Console Application Win32 DLL

Win32 Static Library

1.3 如何获取帮助?

1.4建立第一个应用程序;

使用向导AppWizard生成典型的应用程序——基于多文档的可执行程序 1.5理解AppWizard代码

2.消息与命令

2.1 消息

◆ 消息是Windows编程不同于其它编程方式的地方,如DOS环境下编程。消息就是操作系统通知应用程序某事已发生的一种方式,如:用户已输入、已单击或移动鼠标、打印机已空暇等。

2.2 消息传递

◆ 尽管操作系统用整数来引用消息,但所有消息都通过它们的名字来引用。一个巨大的#define语句将消息名同数值联系起来。不同消息由操作系统或应用程序的不同部分处理。如,当用户在窗口上移动鼠标时,窗口得到一个WM_MOUSEMOVE消息,它几乎全部传送给操作系统去处理。

◆ MFC允许程序员忽略底层消息,并使得在单独类级别上声明每个类处理哪些消息更容易

2.3 消息循环

◆ 任何windows 程序的核心是消息循环,这通常包含 在WinMain() 例程中。 ◆ MFC 通过消息映射来保持消息处理函数与消息处理信息的一致。 2.4 消息映射

◆ 消息映射是进行windows 编程的一部分MFC 方法,用来代替编写向用户的WinProc() 发送消息的WinMain() 函数,及编写检查消息类型的WinProc() 函数。用户只需编写处理消息的函数,并且在用户的类中增加一个消息映射即可,其它一切由MFC 处理。 2.5 消息映射宏

◆ 在类声明的结尾部分,使用宏 DECLARE_MESSAGE_MAP来声明在类定义部分需要消息映射。在*.CPP文件中使用宏 BEGIN_MESSAGE_MAP和END_MESSAGE_MAP来声明消息映射,在两个宏之间声明消息的映射函数。 2.6 常用消息映射宏

◆ ON_COMMAND 用于将特定命令的处理委派给类的一个成员函数。

◆ ON_MESSAGE 用于将用户自定义消息的处理委派给类的一个成员函数。

2.7 ClassWizard帮助用户捕获消息

2.8 添加windows消息处理函数对话框 2.9 命令

◆ 命令是一种特殊的消息类型。用户在任何时候选择一个菜单项,单击一个按钮或告诉系统做什么,windows 都将产生一个命令。 ClassWizard可帮助用户捕获命令。

3.基本控件

[对话框与基本控件] 例子SDI

Windows常用控件 按钮控件 编辑框控件 复选框控件 列表框控件 进度条控件(Progress bar) 滑块控件 上下控件 图象列表(image list) 列表视图控件(list view) 树形控件(tree view) Rich Edit控件 CButton Cedit CCheck CListBox CProgressCtrl CSliderCtrl CSpinButtonCtrl CImageList CListCtrl CTreeCtrl CrichEditCtrl MFC对应的类 4.菜单、工具条、状态条

[菜单]

◆ 编辑菜单(ResourceView)

◆ 捕获消息(ClassWizard)

[工具条]

◆ 工具条改善用户界面,方便用户操作。 ◆ 编辑工具条按钮 ◆ 删除工具栏按钮

◆ 添加工具栏按钮 [状态条]

◆ 例子(SDI)

5.文档、视结构

[简介]

MFC的文档/视图结构把应用程序的数据从用户实际浏览和操纵数据的方法中分离开来。简单的说,文档对象负责存储、加载和保存数据,而视图对象允许用户在屏幕上查看数据,并用适合与应用程序的方法编辑数据。

[了解文档]

CDocument类

一个文档代表了一个数据集合,典型情况下一个文档由用户通过File Open命令打开并通过 File Save命令保存。

用户通过与文档关联的CView对象操作文档。一个文档可以有多个视图关联。 [了解视图]

视图是显示存储在文档对象中的数据,并允许用户修改这些数据。视图对象保持了一个文档对象的指针。为了显示和修改数据,视图对象可用这个指针访问文档的成员变量。 一个视图对象只能与一个文档对象关联。 调用OnUpdate() 函数可以更新一个视图。所有的屏幕显示操作可在从CView继承的派生类的OnDraw成员函数中完成。

CView类的派生类 CCtrlView

实现常用控件的视图 提供基本的文本编辑功能

提供复杂的文本编辑功能

通过使用对话框资源实现窗体式窗口 提供了显示数据库记录的功能

CEditView CRichEditView CFormView CRecordView

CDaoRecordView 一般与DAO数据库类一起使用,其余与CRecordView相同。 CScrollView 提供滚动功能 CListView 在窗口中显示CListView控件 CTreeView

在窗口中显示CTreeView控件

6.图形设备接口

[理解设备环境]

1)户能够显示任何形式的数据,因为窗口中显示的所有东西,不论是文字、表格、位图或是其它任何类型的数据,都是以图形方式显示的。

2)MFC通过将windows的GDI函数和对象封装到其设备环境(DC)类中来帮助用户显示数据。

3)一个设备环境(DC)就是一个数据结构,它对窗口的绘制表面的属性保持跟踪。这些属性包括当前选择的画笔、画刷和用来在屏幕上绘制的字体。一个DC一次只能有一种画笔一种画刷和一种字体。设备环境对象封装了画线、写文本等API函数,所有的画图操作都通过DC对象进行。

4)DC帮助Windows实现了设备无关性。DC能用来输出到屏幕、打印机和元文件。 什么是元文件(metafile) 元文件就是由一系列可变长度结构组成的数组,图片以设备无关的格式存储在结构中。当元文件的记录被转换成设备命令并被合适的设备处理时,元文件被显示。

5)CDC类

CDC就是设备环境对象类。CDC对象提供了操作DC的成员函数。可以通过CDC对象类的成员函数来进行所有的绘图操作。

6)CPaintDC类

◆ CPaintDC 类继承CDC 类;

◆ CPaintDC 类的构造函数自动调用OnPaint 函数,接着就可以在DC 中绘图;类的析构函数自动调用EndPaint 函数。

◆ BeginPaint 函数准备绘图的窗口;EndPaint 函数表明结束窗口的绘图。

◆ 在视图类的OnDraw 函数中,CPaintDC已经由系统准备好,可以直接在OnDraw 中绘图。并且CPaintDC由系统自动释放。 7)CClientDC类

CClientDC对象封装了所有对Windows客户区DC的操作。CClientDC通过调用GetDC函数得到,通过ReleaseDC函数释放。

8)CWindowDC类

CWindowDC对象封装了对整个window窗口,包括框架的操作。

9)CMetaFileDC类

CMetaFileDC对象封装了对一个Windows 元文件的绘图操作。但是必须自己调用OnPrepareDC函数,来准备设备环境。

[图形对象(Graphic Object)]

Windows 提供了多种在DC 中使用的图形对象类。这些类与Windows GDI的句柄类型相对应。

Class Windows handle type

CPen CBrush

HPEN HBRUSH

HFONT HBITMAP HPALETTE

CFont CBitmap CPalette

CRgn HRGN 使用graphic object的一般步骤:

1)定义图形对象,使用对应类的Create函数如CreatePen创建画笔对象。或者在构造函数中进行初始化。

2)将创建的图形对象选进当前设备环境(DC)中,并保存旧的图形对象。 3)完成使用当前图形对象后,将原图形对象选回DC中。

4)保证分配的图形对象在结束使用后被删除。

[注意]: 如果要反复的使用一个图形对象,可以只申请一次,然后在需要的时候将其选入DC中。但是必须确保在不再需要使用图形对象的时候,删除它。

7.编程规范

[书写风格]

大括号的对齐,锯齿状对齐、缩进;使用空白(空字符,空行)以增加可读性。 [命名规范]

匈牙利记法

变量具有一个描述性的名字,如ClassName,名字用大写字母开始;如果变量是一多词名则每个单词词头需大写。然后,在描述性名称前,加上表示变量类型的字母——如,nCount为一整型变量,bFlag为一Boolean型变量。

前缀 a b d h 变量 Array Boolean Double Handle 注释 i l lp lpfn m n p s sz u C Integer Long Long pointer to Long pointer to function Member variable Integer Pointer to String Zero terminated string Unsigned integer Class “index into” “number of” [注释规则]

1)函数注释 函数开头必须注明函数功能、参数、返回值 2)变量注释 应说明变量的作用

3)其它注释 每个功能模块应加注释,如一个循环体、一个判断等都需要加注释。

第三讲 地理信息系统基本概念

第四讲 MAPGIS的基本概念和体系结构

1.MAPGIS二次开发的基本概念

成熟实用的地理信息系统(GIS)的重要标志就是它提供给用户的二次开发能力。MAPGIS提供完整的二次开发函数库。用户完全可以在MAPGIS平台上开发面向各自领域的应用系统。

Windows 98、Windows 2000、 Windows NT 图1-1 基于MAPGIS平台的应用程序 操作系统、MAPGIS开发库及MAPGIS应用程序的相互关系如下图所示:

MAPGIS应用程序 发库被封装于若干动态链接库(DLL)中。

MAPGIS 空间分析 窗口操作 ? 图库操作 图形、图象I/O 开发库 工作区管理 目前MAPGIS二次开发库主要以API函数、MFC类库、ActiveX 控件三种方式提供。开

API函数在使用方法上与Windows的API函数完全一样,因此是独立于开发工具的。无论您使用VC++、VB还是BC++、Dephi?,您在这些工具中如何调用Windows的API函数,您就怎么调用这些二次开发函数好了。

MAPGIS类库是为基于MFC(Microsoft Foundation Class)的开发者提供的多个可重用基类,将应用程序所需的常见基本功能作了封装,使用便利,改动灵活。开发者只需从类库派生即可使自己的程序获得从窗口显示控制到图形查询编辑的各项功能。

ActiveX 控件是MAPGIS完成组件化改造的成果之一,它们基于COM++模型,使得二次开发更为快捷便利,代码的可复用性更高。

上述各类开发接口提供了从最基本数据单元的读取、保存、更新和维护到MAPGIS地图库的建立和漫游,以及空间分析,图象处理等一系列功能。其中,API函数是基础,使用上最灵活,但技巧性要求也最高。所以本书大量篇幅用于介绍API函数。MAPGIS将不断丰富完善各类二次开发接口,以多种开发手段满足不同层次、不同应用的需求。这些函数所在的头文件如下表所示。

函数库名称 各种头文件 工作区基础函数 图形显示输出 窗口操作API函数 图形显示函数 图形编辑函数 拓扑操作函数 剪贴板操作函数 数字化设备参数设置及初始化调用函数 图框生成函数 投影变换 工作区投影变换 工程管理及拼版文件操作 窗口操作类库 输入编辑类库 工程管理类库 地图库读取显示 空间分析函数 Tin基本操作函数 Tin工作区函数 网络分析函数 统计分析和统计图制作函数 转换函数 客户化菜单 图像输入输出 表1 二次开发头文件

c,c++说明文件 MapGis.h Win_area.h Map_out.h Win_oper.h Mapdisp.h Mapedit.h Gistopo.h clippaste.h W32_Dig.h frmdll32.h projdll.h cordcvt.h Map_prj.h CGisView.h CGisEdit.h CPrjEdit.h Dbs_View.h Spc_anly.h TinBas32.h Tin_area.h Net_oper.h Att_Sta.h GisConv.h Custom.h msiio.h 2.MAPGIS基本术语

下面介绍MAPGIS系统中经常使用的一些基本概念。

地图:是按一定的数学法则和特有的符号系统及制图综合原则将地球表面的各种自然和社会经济现象缩小表示在平面上的图形,它反映制图现象的空间分布、组合、联系及在时空方面的变化和发展。

窗口:是用户坐标系中的一个矩形区域。用户可以改变这个矩形的大小、或移动位置来选择所要观察的图形。窗口就象照相机的取景框,当我们瞄准不同的地方,就选取了不同的景物。离景物越远框内包括的景物越多而成像就小;当我们靠近它,所包括的景物越少,成像越大。利用窗口技术,我们可以有选择的考察图形的某一部分,观察图形的细致部分或全局。

视区:是设备坐标系中的矩形区域,它是图形在设备上的显示区。可视区是在一定高程和一个或多个视点内,通过计算所得到的一个或多个视点的可见区域。

图层:用户按照一定的需要或标准把某些相关的物体组合在一起,我们称之为图层。如地图中水系构成一个图层,铁路构成一个图层等。我们可以把一个图层理解为一张透明薄膜,每一层上的物体在同一张薄膜上。一张图就是由若干层薄膜叠置而成的,图形分层有利于提高检索和显示速度。

靶区:是屏幕上用来捕获被编辑物体(图形)的矩形区域,它由用户在屏幕上形成。 控制点:控制点是指已知平面位置和地表高程的点,它在图形处理中能够控制图形形状,反映图形位置。

点元:点元是点图元的简称,有时也简称点,所谓点元是指由一个控制点决定其位置的有确定形状的图形单元。它包括字、字符串、子图、圆、弧、直线段等几种类型。它与“线上加点”中的点概念不同。

弧段:弧段是一系列有规则的,顺序的点的集合,用它们可以构成区域的轮廓线。它与曲线是两个不同的概念,前者属于面元,后者属于线元。

区/区域:区/区域是由同一方向或首尾相连的弧段组成的封闭图形。

拓扑:拓扑亦即位相关系,是指将点、线、及区域等图元的空间关系加以结构化的一种数学方法。主要包括:区域的定义、区域的相邻性及弧段的接序性。区域是由构成其轮廓的弧段所组成,所有的弧段都加以编码,再将区域看作由弧段代码组成;区域的相邻性是区域与区域间是否相邻,可由它们是否具有共同的边界弧段决定;弧段的接序性是指对于具有方向性的弧段,可定义它们的起始结点和终止结点,便于在网络图层中查讯路径或回路。拓扑性质是变形后保持不变的属性。

透明输出:与透明输出相对的为覆盖输出。用举例来解释这个名词,如果区与区、线与区或点图元与区等等叠加,用透明输出时,最上面的图元颜色发生了改变,在最终的输出时最上面图元颜色为它们的混合色。最终的输出如印刷品等。

数字化:数字化是指把图形、文字等模拟信息转换成为计算机能够识别、处理、贮存的数字信息的过程。

矢量:是具有一定方向和长度的量。一个矢量在二维空间里可表示为(Dx,Dy),其中Dx表示沿x方向移动的距离,Dy表示沿y方向移动的距离。

矢量化:矢量化是指把栅格数据转换成矢量数据的过程。

细化:细化是指将栅格数据中,具有一定宽度的图元,抽取其中心骨架的过程。 网格化(构网):网格化是指将不规则的观测点按照一定的网格结构及某种算法转换成有

规则排列的网格的过程。网格化分为规则网格化和不规则网格化,其中规则网格化是指在制图区域上构成有小长方形或正方形网眼排成矩阵式的网格的过程;不规则网格化是指直接由离散点连成的四边形或三角形网的过程。网格化主要用于绘制等值线。

光栅化:光栅化是指把矢量数据转换成栅格数据的过程。 曲线光滑:就是根据给定点列用插值法或曲线拟合法建立某一符合实际要求的连续光滑曲线的函数,使给定点满足这个函数关系,并按该函数关系用计算加密点列来完成光滑连接的过程。

结点:结点是某弧段的端点,或者是数条弧段间的交叉点。

结点平差(顶点匹配):本来是同一个结点,由于数字化误差,几条弧段在交叉处,即结点处没有闭合或吻合,留有空隙,为此将它们在交叉处的端点按照一定的匹配半径捏合起来,成为一个真正结点的过程,称为结点平差。

BUF检索:本来是靠近某一条弧段X上的几条弧段,由于数字化误差,这几条弧段在与X弧段交叉或连接处的结点没有落在X弧段上,为此将X弧段按照一定的检索深度检索其周围几条弧段的结点,若落在该深度范围内,就将这些结点落到X弧段上,从而使这些弧段靠近于X弧段,我们称这个过程为BUF检索。

缓冲区(Buffer):是绕点、线、面而建立的区域,可视为地物在一定空间范围内的延伸,任何目标所产生的缓冲区总是一些多边形,如建立以湖泊和河道500米宽的砍伐区。缓冲分析的应用包括道路的噪声缓冲区、危险设施的安全区等。

裁剪:裁剪是指将图形中的某一部分或全部按照给定多边形所圈定的边界范围提取出来进行单独处理的过程。这个给定的多边形通常称作裁剪框。在裁剪实用处理程序中,裁剪方式有内裁剪和外裁剪,其中内裁剪是指裁剪后保留裁剪框内的部分,外裁剪是指裁剪后保留裁剪框外面的部分。

属性:就是一个实体的特征,属性数据是描述真实实体特征的数据集。显示地物属性的表通常称为属性表,属性表常用来组织属性数据。

重采样:就是根据一类象元的信息内插另一类象元信息的过程。

遥感:广义上讲,遥感就是不直接接触所测量的地物或现象,远距离取得测量地物或现象的信息的技术方法。狭义而言,主要指从远距离、高空以至外层空间的平台上,利用可见光、红外、微波等探测仪器,通过摄影和扫描、信息传感、传输和处理,从而识别地面物质的性质和运动状态的现代化技术系统。

监督分类:根据样本区特征建立反射与分类值的关系,然后再推广到影像的其它位置。它以统计识别函数为理论基础。而非监督分类以集群理论为基础,自动建立规则。 网络(Network):由节点和边组成的有规则的线的集合,如道路网络、管道网络。节点是线的交叉点或线的端点,边是数据库模型中的链(即定义复杂的线或边界的坐标串),节点度是节点处边的数目。网络分析多种多样,如交通规划、航线安排等。

TIN:是由一组不规则的具有X、Y坐标和Z值的空间点建立起来的不相交的相邻三角形,包括节点、线和三角形面,用来描述表面的小面区。TIN的数据结构包括了点和它们最相邻点的拓扑关系,所以TIN不仅能高效率地产生各种各样的表面模型,而且也是十分有效的地形表示方法。TIN的模型化能力包括计算坡度、坡向、体积、表面长,决定河网和山脊线,生成泰森多边形等。

数字高程模型(DEM):即Digital Elevation Model,是数字形式的地形定量模型。

数字地形模型(DTM):即Digital Terrain Model,是数字形式表示的地表面,即区域地形的数字表示,它是由一系列地面点的X,Y位置及其相联系的高程Z所组成。这种数字形式的地形模型是为适应计算机处理而产生的,又为各种地形特征及专题属性的定量分析和不

同类型专题图的自动绘制提供了基本数据。在专题地图上,第三维Z不一定代表高程,而可代表专题地图的量测值,如地震烈度、气压值等。

地图投影(Map Projection):地图投影是按照一定的数学法则,将地球椭球面经纬网相应投影到平面上的方法。

坡度和坡向:若输入高程,则通过计算相邻象元值的差异可求得坡度;斜坡倾斜的水平方向称为坡向。

3.MAPGIS的数据管理(工作区)

3.1工作区的概念 MAPGIS数据管理的核心就是对工作区的操作。

工作区是MAPGIS提出的一个概念,简单地说,工作区就是一个数据池,存放实体的空间数据、拓扑数据、图形数据和属性数据,每个工作区都对应于一个MAPGIS数据文件。MAPGIS开发函数库提供对工作区实施操作的一系列函数,如将工作区中的内容存盘,从盘上将数据装入工作区,对工作区中内容进行添加、修改、删除、检索等等。对硬盘数据的存取及虚拟内存的管理等等复杂繁琐的工作无需应用程序的编写者去关心,而是由MAPGIS工作区管理模块自动完成。如图所示。由此可见,深入了解工作区的逻辑结构和工作区操作函数的使用,是进行成功的二次开发的关键。 3.2 .工作区管理模块的地位

工作区(空间数据、图形数据及属性数据) 工作区管理模块的地位

3.3工作区的分类 MAPGIS将工作区分为点、线、区、网、表五种类型,它们的差别主要表现在其中包含的空间实体的类型不同。详见下表:

MAPGIS应用程序 工作区API函数界面 工 作 区 管 理 模 块 工作区类型 点工作区(.WT文件) 线工作区(.WL文件) 区工作区(.WP文件) 实体类型 点(PNT) 线(LIN)、结点(NOD) 线(LIN)、结点(NOD)、区(REG) 网工作区(.WN文件) 表工作区(.WB文件)

线(LIN)、结点(NOD)、网(NET) 无空间实体,仅有表格记录 各类工作区中可以包含的实体类型

由于不同种类的工作区中空间实体的类型不同,各类型的工作区所适用的数据操作函数

也就不同。例如,对点工作区只能使用操作点实体数据的函数;而对区工作区则可对线、结

点和区实体的数据进行操作。

4.MAPGIS的空间实体及其数据组织

空间实体是MAPGIS数据操作的基本单位,在一个工作区中,一类实体可有多达2G的个体,每个个体都有唯一的序号,称为实体号(点号、线号、区号、网号、记录号等)。对实体数据的存取主要依据实体号。 每个实体在工作区中都存储有对应的空间数据、拓扑数据、图形参数及属性记录。当然,实体类型不同,上述几方面的数据就有不同的特点,见下表。 1.实体类型:点,线,区,节点,网

2.实体数据:空间数据,拓扑数据,图形数据,属性数据 3.实体数据的逻辑组织

实体类型 空间数据及拓扑数据 图形参数 PNT_INFO(字符串、点PNT 位置(x,y)D_DOT 位置(x0,y0),?,(xn,yn) 拓扑LIN_TOP 位置(x,y)D_DOT 连接的弧段(l0,l1,?,ln) 结点NOD PNT_INFO,也可没缺省属性 文本、子图、圆、弧、ID(长整型) 图象) LIN_INFO ID(长整型) 长度(浮点型) 线LIN 附加数据:连通方阵、中心数有图形参数 据、站点数据、转角数据等 ID(长整型) 区REG 区数据:边界弧段号 REG_INFO ID(长整型) 周长(浮点型) 面积(浮点型) 网NET 网数据:组成网的弧段号 NET_INFO ID(长整型) 不同类型实体的相关数据

说明:1. D_DOT是描述二维空间位置的数据结构,就是(x,y)座标对。见后边“宏定义及数据结构”。

2. 3.

LIN_INFO是描述线的拓扑关系的数据结构,主要记录线两端的结点、线两边的区等信息。见后边“宏定义及数据结构”。

PNT_INFO、LIN_INFO、REG_INFO、NET_INFO分别是描述点、线、区、网图形特征(用于显示或输出)的数据结构,其定义见后边“宏定义及数据结构”。

4. 上表中仅列出不同类实体的缺省属性域,它们是最基本的。用户可以在此基础上任意扩充

新的各种数据类型的数据域以满足自己的需要。

对每种空间实体的空间数据、拓扑数据、图形参数及属性记录,MAPGIS都提供相应的函数来实施获取、修改、删除等操作。

下面以例子来详细说明线实体、结点实体、区实体在工作区中的数据组织。

n1 n4

L1

n2

R1 R2 L3

L4 L2 n3 一个区工作区中的空间实体 图1-3给出了一个区工作区中的空间实体。在这个工作区中有四条线(线号分别用L1、L2、L3、L4表示),有四个结点(结点号分别用n1、n2、n3、n4表示),有两个区(设区号分别为R1、R2)。

1、线实体

MAPGIS中的线由多个座标点组成,线实体的空间数据就是存放在工作区中的座标点序列(D_DOT结构)。如果线L1由8个点组成,它的空间数据就如下所示:

(x0,y0)

n3

N1 0 R1 0 0 (x1,y1) ? (x7,y7) 线拓扑(LIN_TOP结构)记录线两端的结点和线两旁的区。如线L2的拓扑数据如下:

起始结点

终止结点 左区 右区

而L4的拓扑数据如下:

N4

n4 1 2 0 0 2、结点实体

结点的空间数据与点实体一样,是二维座标点,其拓扑数据记录它所连接的线,如n1的拓扑数据是:

L1

而n4的拓扑数据是:

L4

3、区实体

L2 区由线实体(在区工作区中又被称为弧段)围成,它的空间数据主要记录这些线的序号。如果线L1、L2、L3、L4的方向如图1-3所示,且所含座标点的数目分别为d1、d2、d3、d4,假设我们将顺时针方向定为R1的方向(这并不是硬性的规定,也可以将一个区的方向定为逆时针),则区R1的空间数据如下:(p137)

D1+d2+d3+d4+2 注意:

第一个单元存放的并不是线号,而是全部线的座标点数目的总和加上区边界的圈数; 边界各圈的线号用0相隔;

在数据中与区方向一致的线用正数表示,与区方向相反的线则存储线号的相反数。

4、属性记录

图1-3中各个实体对应的属性记录都具有如下结构:

偏移字节 0 1(fldEntry[0].fieldoffset) fldEntry[1].fieldoffset Flag 字段1:ID(长整型) 字段2 … 字段m L1 -L3 L2 0 L4

删除标记(0: 存在;1:已删除) 5.MAPGIS的C++类组织

MAPGIS二次开发类库是建立在MAPGIS API之上的一个类库层,用于支持基于MFC类库的面向对象的Windows程序设计。MAPGIS二次开发类库,提供了一套强有力的C++类,它屏蔽了基于MAPGIS API之上开发MAPGIS 实用程序的许多复杂性,同时仍然允许有经验的程序员使用底层的MAPGIS API功能。如何有效地使用这个类库,且看下面介绍。

CView CGisView

CGisEditView CPrjEditView 图 13-1 MAPGIS二次开发类库结构图

CGisView类继承了Visual C++的CView类,它封装了窗口管理的各种功能及操作,它管理了窗口的图形显示参数、操作状态,滚动条的位置、范围等基本窗口属性,以及放大窗口、缩小窗口、移动窗口、显示范围、显示比例、坐标转换等功能。CGisView 类还支持窗

口的保护和快速恢复等功能。CGisView类是MAPGIS类库中大多数类的基类。

CGisEditView 类继承了CGisView 类。它封装了MAPGIS编辑处理的基本数据对象和方法。包括几乎所有的点、线、区的编辑功能以及图层的处理函数、矢量化函数、节点平差函数、数字化函数、最基本的文件操作功能。CGisEditView类及其基类组成了十分强大的图形编辑函数库。

用户开发自己的软件时最好是继承CGisEditView类,这样用户可以同时使用BaseEditWindow 、CGisView 、CGisEditView类及VC++的Cview类所提供的所有功能。 CPrjEditView类继承了CGisEditView 类,它集成了对工程文件进行编辑处理所必需的数据对象的方法,具有对整个工程文件的各个文件编辑处理功能。

6.MAPGIS的开发环境介绍

使用VC++开发MAPGIS应用程序的最快速有效的方法就是使用MAPGIS类库。这些类已经为用户的程序与MAPGIS操作平台的接口做好了准备,用户可以体会到使用这些类可以很容易地实现MAPGIS系统里的功能,而且在实现MAPGIS系统功能的基础上用户还可以随意地添加自己想要的功能。下面我们以CGisEditView类为例讲述如何构造一个简单的MAPGIS图形编辑器的方法和基本步骤。 第一步、建一个Visual C++的项目。打开Visual C++工作环境,选择File菜单New命令,在弹出的对话框中选择Projects页的MFC AppWizard(EXE)项并在Project name编辑框中敲入工程名(例如:engineer),然后单击OK。这样便进入了AppWizard(向导)的第一步,在这一步里用户要选择工程类型,可以选择单文档或多文档工程(基于对话框的工程不适合我们建MAPGIS工程),初学者最好选单文档类型;单击Next进入向导的第二步、第三步、直到完成(Finish之后OK),这几步用户可以采用默认设置。到此为止一个VC的项目已建好,然后用户的工作就是在这个项目中实现MAPGIS平台中的功能及自己想要的其他功能。

第二步、要完成的工作是将工程中的视图类改为继承CGisEditView类。具体操作是打开工程中的视图类的两个文件(*View.h、*View.cpp),用Visual C++查找替换功能(Edit菜单下的Rplace命令或热键Ctrl+H)分别将这两个文件中的CView字符串全部替换为CGisEditView,替换完毕,在工程中视图类的定义前面加入#include “cgisedit.h”,这样就完成了CGisEditView类的继承。

第三步、调用CGisEditView类中的OnDraw(pDC)函数,以完成绘图工作的预先处理。具体操作方法:在视图类的OnDraw(CDC* pDC)函数中加语句CGisEditView::OnDraw(pDC)。见下面示例:

void CEngineerView::OnDraw(CDC* pDC) { }

图12-3 添加函数实现图形显示

CEngineerDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);

// TODO: add draw code for native data here CGisEditView::OnDraw(pDC);

第四步、对Visual C++的工作环境进行必要的设置,这些设置很重要。 第1项(字节)设置:选择Project菜单下的Settings命令,在C/C++页面上,Category一栏选择 Code Generation,并将Struct Member alignment设定为1 Byte。

第2项(输出目录)设置:把生成的可执行文件输出到MAPGSI动态连接库所在的目录下。

第3项(包含库)设置:设置头文件及库文件的路径。选择Tools菜单下的Options命令

完成这几步用户就可以进行编译连接,执行,在客户区单击鼠标右键你会发现弹出一个有关MAPGIS操作的快捷菜单。这时用户可以使用CGisEditView类及其基类中的函数设计自己的基于MAPGIS的图形软件了。

CPrjEditView类(或CGisView类)的使用方法和CGisEditView类的使用方法基本相同,只不过要继承CPrjEditView类(或CGisView类)。

第五讲MAPGIS空间数据存取和属性编辑

1.工作区操作

1.1 工作区介绍

逻辑缓冲池 工作区 (实体数据) 网络数据库 本地文件 物理存储 1.2工作区操作函数

[工作区操作流程]

1)初始化工作区实例(_InitWorkArea) 循环[2>,5>]

2)打开工作区(点,线,区,网,表)(_OpenArea) 3)装文件至工作区(_LoadFile) 4)...实体(图形,属性)操作,表格操作...... 5)关闭打开的工作区(_CloseArea) 6)释放工作区实例(_FreeWorkArea)

C示范:打开点工作区,装入点文件

AHINST AHInst; short AiPnt;

AHInst = _InitWorkArea(m_hInstance); AiPnt =_OpenArea(AHInst,PNT); If(_LoadFile(AiPnt) > 0) {

…..//实体操作

}

_CloseArea(AiPnt); _FreeWorkArea(AHInst);

1.3 工作区函数

1>AREA_HINST _InitWorkArea(HINSTANCE hInst); 2>int 3>short 4>int _FreeWorkArea(AREA_HINST ahInst);

_OpenArea(AREA_HINST,short type);

_CloseArea(short ai); (_SetChangeFlag(short ai,char flag);) 5>short

_LoadAFile(char * datName,short ai);

short _LoadFile(short ai); 6>char _GetAreaType(short ai); 7>short _IsAreaEmpty(short ai); 8>short _IsOpenArea(short ai);

9>short _GetAreaNumber(AREA_HINST ahInst); 10>short

_GetFirstAreaNo(AREA_HINST ahInst);

11>short _GetNextAReaNo(AREA_HINST ahInst); 12>short

_SaveFile(short ai,short ver=VERSION); _SaveAFile

C示范:读取属于AHInst实例的所有工作区 short i,ai,an;

an = _GetAreaNumber(AHInst); ai = _GetFirstAreaNo(AHInst);

for(i = 0; i < an; i++,ai = _GetNextAreaNo(AHInst)) { //使用工作区ai... }

2.空间实体操作

实体存取主要依据实体数据的唯一标识:实体号 实体(Lin,Pnt,Nod,Reg,Net) 2.1 取实体个数

_Get...Num: 逻辑数,物理数 2.2 取实体空间数据,图形数据

_Get... 2.3 实体操作

1)取实体图形参数 _Get...Info 2)更新实体图形参数 _Update....Info 3)添加实体 _Append... 4)删除实体 _Del... 5)撤销删除实体 _UnDel...

[注意]:函数返回:1==>成功;0==>失败;-1==>该图元被删除 C示范:从给定的ai号工作区重读区所有的线

long i,linN; long len; LIN_INFO linf; D_DOT *lxy;

_GetLinNum(ai,&i,&linN);//取线实体数,i返回逻辑数,linN返回物理数 for(i = 1;i < linN; i++) {

if(_GetLin(ai,&lxy,&len,&Linf) <= 0) continue;

//处理线实体代码 //... }

2.4 特殊函数

线(拓扑)==>_GetLinTop;_WriteLinTop;_ClearLinTop 区==>合并_UnionRegAtoB,分裂_SplitReg 2.5 拷贝操作

_CopyPart...(_CopyPartLin...) _CopyAll...(_CopyAllLin...) _CopyList...(_CopyListLin...)

3.属性(属性结构)操作

3.1属性结构

1)属性结构描述

CAtt_Stru

2)属性结构函数

a.取属性结构:_GetAttStru b.设置属性结构:_SetAttStru

c:添加属性结构字段:_AppendStruFld

d:删除属性结构字段:_DelStruFldOnNumb, _DelStruFld

e:编辑属性结构:_EditStruct f:浏览属性结构:_ViewStruct

g比较属性结构: _IsSameAttStru

C示范:向给定的ai号点工作区的点属性结构添加double类型字段”产量”,字符串类型字段”地方”;

CFIELD_HEAD fldEntry;

lstrcpy(fldEntry.fieldname,”产量”); fldEntry.fieldtype=DOUBLE_TYPE fldEntry.msk_leng=15;

fldEntry.point_leng=6;

_AppendStruFld(ai,PNT,1,&fldEntry); lstrcpy(fldEntry.fieldname,”地方”); fldEntry.fieldtype=STR_TYPE fldEntry.msk_leng=64;

_AppendStruFld(ai,PNT,1,&fldEntry);

3.2 属性操作

1)属性数据表示===>属性表 2)属性操作函数

a.取属性:_GetAtt

b.写属性:_WriteAtt

d:编辑属性结构:_EditStruct

e:浏览属性结构:_ViewStruct 3)字段操作函数 a.取字段值

_CvtFldToString,_CvtFldToString1 b.设置字段值

_SetFld,_SetFldFromStr

_SetFldOnNumb,_SetFldOnNumbFromStr

设置字段值之后,要写属性_WriteAtt,才能将字段值写入工作区

4)图形数据和属性联动闪烁显示 5)属性数据的输入,输出 6)属性连接

long WINAPI _LinkTbl1(CLinkTblInfo &linkTblInfo); 7)属性外挂

4.网络介绍

4.1 MAPGIS网络环境的建立 4.2函数

1)装文件_LoadFile

2)存文件_SaveFile 3)锁图元 _Lock… 4.3 其他概念 1)数据源 2)用户,角色 3)访问权限 4)加锁

第六讲 图形显示输出及窗口操作

1. 图形显示输出

1.1显示输出的基本原理

1)逻辑坐标、设备坐标、窗口坐标、屏幕坐标 基本概念:

逻辑坐标:逻辑坐标又称图形坐标或用户坐标,(现统称逻辑坐标),是用户处理自己的图形实际所采用的坐标系。例如:用户自定义坐标、大地坐标、地理坐标。

设备坐标:是图形设备的坐标系。数字化仪该设备的坐标原点一般在中心;笔式绘图仪以步距为单位,以中心或某一角为原点;在MAPGIS二次开发中,应用程序窗口也是一种

设备,它的设备坐标称为窗口设备坐标,它把某窗口的客户区当作将要绘图的设备,该坐标系以窗口客户区左下角为原点,右手坐标系。

窗口坐标:原点在指定窗口客户区左上角的坐标,以象素为单位,左手坐标系。 屏幕坐标:原点在屏幕左上角的坐标,以象素为单位,左手坐标系。2. 各坐标系之间的坐标转换:

(1)逻辑坐标<====>设备坐标:

_LpToDp如果函数要求使用设备坐标,而当前数据是逻辑坐标,则需要调用将逻辑坐标转换为设备坐标再调用;

_DpToLp如果函数要求使用逻辑坐标,而当前数据是设备坐标,则需要调用将设备坐标转换为逻辑坐标再调用;

(2)窗口坐标<====>设备坐标:_WpToDp、_DpToWp (3)窗口坐标<====>逻辑坐标:_WpToLp、_LpToWp

(4)窗口坐标<====>屏幕坐标: 这两个坐标系之间的转换比较简单,不需要专门的函数,只需获取应用程序窗口在屏幕上的相对位置,然后进行简单的平移计算即可。

2)HDC、MyDC

DC、HDC:熟悉Windows编程的人,对DC、HDC的概念一定不会陌生。设备描述表(DC)不仅描述了设备对象、设备对象的属性以及图形显示模式;同时,还指向了一个实际的物理输出设备,包括设备名称、设备驱动程序以及其他一些信息。实际用GDI函数进行编程时,我们经常使用的是一个指向DC的句柄HDC。利用HDC,我们就可以避开千变万化的外部输出设备,以一种透明、简便的方式实现对图形设备的控制,最终达到我们所要实现的目的。在开始绘图前,如果您调用Windows API绘图函数,首先需获取当前绘图窗口的HDC。绘图结束后应释放该DC。

MyDC: MAPGIS引入一个新的概念——显示对象(MyDC),有时侯也称显示设备句柄,类似于Windows中的HDC。在显示对象中集成了Windows的DC和MAPGIS基本显示处理的函数,MAPGIS的所有显示函数都是针对某一个显示对象的,即所有显示都显示在这个对象所联系的窗口上。每个窗口都对应不同的显示对象,都可以设置不同的图形模式和显示参数。 在开始绘图前,如果您使用MAPGIS API绘图函数,首先需调用_GetMyDC获取当前绘图窗口的MyDC。绘图结束后应调用_DeleteMyDC释放该DC。

3)显示模式、显示参数、显示范围;

显示模式:MAPGIS的显示模式概念与Windows的显示模式概念类似。显示模式将决定最终的显示效果。函数_SetMyDCMode将显示对象设置为多边形交错填充模式、设备左下角为原点、右手坐标系。

显示参数:定义了视口原点坐标,x、y方向的缩放比例,显示角度等信息。通过对显示参数的设置,可实现地图的移动、放大、缩小等操作。函数_SetDispParam实现显示参数的设置。函数_GetDispParam实现显示参数的读取。

显示范围:窗口所显示的地图的范围。函数_SetDispRect实现显示范围的设置。函数_GetDispRect实现显示范围的读取。

4)还原显示、坐标点显示;

还原显示:当还原显示状态为真时,显示图元的函数按模拟输出的标准显示,所用的线型、图案等都显示出来,在这个状态下显示速度较慢。在非还原显示状态时,线型、图案等都不显示,汉字显示等函数也作了简化处理,故显示速度较快。可用_SetOriginalDisp函数来设置还原显示或非还原显示状态。

坐标点显示:在坐标点显示状态下,显示图元的函数在图元的坐标点处显示一个小的红

十字,在编辑时可作为参考。可用_SetCoordPntDisp函数来设置坐标点显示或非坐标点显示状态。

5)调色板、笔、刷子;

调色板:MAPGIS有一套自己的调色板,该调色板是针对地图着色而设计的。调用_SetMyDCPalette函数可以将原来的Windows逻辑调色板替换为MAPGIS调色板。 笔:定义了画笔的颜色、笔宽、模式等信息。使用前,需用_SetPen函数来定义画笔;使用结束,应用函数_CleanPen来清除画笔。画线、画圆、画弧、显示字符串等函数多用到画笔。

刷子:定义了刷子的颜色、填充图案、笔宽、模式等信息。使用前,需用_SetBrush函数来定义刷子;使用结束,应用函数_CleanBrush来清除刷子。与画笔不同的是,刷子多用于与填充有关的函数。

1.2图形显示输出基本函数

1)显示对象句柄的获取和删除:

MyDC _GetMyDC(HWND hwnd,PAINTSTRUCT *lpps=NULL);

void _DeleteMyDC(MyDC mdc); 2)设置显示对象图形模式

void _SetMyDCMode(MyDC mdc); 3)设置设备调色板

void _SetMyDCPalette(MyDC mdc);

4)显示参数的获取和设置:

short _SetDispParam(MyDC mdc,double fx0,double fy0,double fScalex,double fScaley = 0,double fAngle = 0);

short _GetDispParam(MyDC mdc,double *pfx0,double *pfScalex,double *pfScaley= NULL,double *pfAngle=NULL);

5)显示范围的获取和设置:

short _SetDispRect(MyDC mdc,D_RECT frc); short _GetDispRect(MyDC mdc,D_RECT *frc); 6)设置特殊显示状态:

short _SetOriginalDisp(MyDC mdc,short Origif); short _SetCoordPntDisp(MyDC mdc,short sCoord); short _SetMessageDisp(MyDC mdc,short Dispif); 7)颜色的锁定与解除:

void _LockColor(MyDC mdc,COLORREF col); void _UnLockColor(MyDC mdc); short _GetLockState(MyDC mdc); 8)绘图工具设置:

void _SetPen(MyDC mdc,int penno,int color);

void _CleanPen(MyDC mdc);

void _SetBrush(MyDC mdc,long bcol, short pno=0, double phei=1,long pcol=0); void _CleanBrush(MyDC mdc);

void _SetPenColor(MyDC mdc, COLORREF clr); void _CleanPenColor(MyDC mdc);

int _SetPenMode(MyDC mdc,int nMode); int _GetPenMode(MyDC mdc);

*pfy0,double

9)逻辑坐标(或图形坐标)与设备坐标互换:

void _LpToDp(MyDC mdc,D_DOT *pdP);

void _DpToLp(MyDC mdc,double *pfx,double *pfy); 10)显示输出整个工作区:

short _DispPntArea(MyDC mdc,short ai,short layon=0); short _DispLinArea(MyDC mdc,short ai,short layon=0); short _DispRegArea(MyDC mdc,short ai,short layon=0); 11)在用户坐标系下显示输出实体:

short _DispLin(MyDC mdc,short ai,long gno,long col=0); short _DispLin(MyDC mdc,short ai,long gno,long col=0); short _DispReg(MyDC mdc,short ai,long gno,long col=0); 12)在设备坐标系下显示输出实体 :

void _DrawLine(MyDC mdc,POINT *xy,long len, long col=0);

void _RegionFill(MyDC mdc,POINT *xy,int *ne, int regnum,int col=0); short _DispString(MyDC mdc,double x,double y,float h, float w,char *str,short zt,short zx,float ang, float sp,char pl,long col=0);

short _DispText(MyDC mdc,double x,double y,float px, float py,float h,float w,char *str,short zt, short zx, float ang, float sp,float ls,char pl,long col);

short _DispSubgr(MyDC mdc,long subno,double x,double y,double hei,double wid,double ang,long col=0);

13)基本绘图函数 :

void _Line(MyDC mdc,double x1,double y1, double x2,double y2); void _LineTo(MyDC mdc,double x,double y); void _MoveTo(MyDC mdc,double x,double y);

void _Arc(MyDC mdc,double r,double ang1, double ang2); void _Circle(MyDC mdc,double rad); void _CircleFill(MyDC mdc,long rad);

void _PolyLine(MyDC mdc,D_DOT *lxy,long *ne, int na); void _PolyGon(MyDC mdc,D_DOT *lxy,long *ne,int na);

void _Rect(MyDC mdc,double x1,double y1, double x2,double y2); 14)取符号数

short _GetPatternNum(void);

取图案数

short _GetLineStyleNum(void); 取线型数 short _GetColorNum(void); 取颜色数 short _GetSubGraphNum(void); 取子图数 15)取某线型的辅助线型数 Short _GetFltpNum(int ltp)

16)取子图的最小范围

short _GetSubGraphRect(int subno,double x,double y,float hei,float wid,float ang,D_RECT* rc);

17)RGB对应的MAPGIS颜色阶

short _FindNearColor(int r,int g,int b); 18)MAPGIS颜色阶对应的RGB值

short _GetAColorRGBValue(int cno,int *r,int *g,int *b);

19)MAPGIS颜色阶对应的CMYK值

short _GetAColorCMYKValue(int cno,int *k,int *c,int *m,int *y);

2. 窗口处理

2.1窗口处理的主要作用

窗口处理函数的作用主要表现在两个方面:

1)用于优化窗口消息的处理效率,跟踪记录窗口状态。当窗口处于非活动状态时,记录窗口无效范围,并保存窗口被遮挡的画面,需要时快速更新窗口显示内容。

2)自动记录跟踪当前窗口所对应的用户图形范围,完成图形坐标、设备坐标、窗口坐标间的转换,自动实现对窗口图形的放大、缩小、复位等操作。

这里讲解的函数全部是基于窗口句柄的API函数,如果用户在开发中使用MFC(Microsoft Foundation Class)框架,建议使用MAPGIS提供的MFC类,如CGisView、CgisEditView等,它们的使用要简单得多。

2.2窗口显示参数

窗口操作用到下面的窗口显示参数结构WIN_ORG: typedef struct { double x0,y0; //视口左下角(原点)

D_RECT frc; //显示范围 double r; //显示比例

}WIN_ORG; x0,y0为窗口原点对应的图形坐标,窗口原点为左下角,frc为显示范围的图形坐标,r为显示比例,即屏幕窗口上的距离与图上距离之比。 2.3窗口处理基本函数

1)窗口显示内容的保存和快速显示:

SetPaintFunction _OwnerDraw ProcSYSCOMMAND ProcACTIVATE ProcPAINT VscrollMap HscrollMap

DelWinParam PopupWinImage

2)窗口显示范围的管理 :

short _GetWinDispParam(HWND hwnd,WIN_ORG *wxy); short _SetWinDispParam(HWND hwnd,WIN_ORG wxy); short _GetWinDispRect(HWND hWnd,D_RECT *frc); short _ResetWinDispRange(HWND hwnd,D_RECT rc); short short short short

_ResetWinDispRate(HWND hwnd,double rate); _GetWinMapRange(HWND hwnd,D_RECT *frc); _ResetWinMapRange(HWND hwnd,D_RECT *frc); _OpenWindowRc(HWND hWnd,RECT *rc);

short _EnlargeWindow(HWND hwnd, long x,long y); short _ReduceWindow(HWND hwnd, long x,long y); short _RestoreWindow(HWND hwnd,short…ahInst=0); short _PrevWindow(HWND hwnd);

short _ MoveWindow (HWND hWnd, long dx,long dy); 2.4CGisView显示原理

1)将所有CView替换为CGisVew;

(当然,需包含#include “CGisVew.h”头文件。) 2)在C*View::OnDraw()函数中,在最后加入

“CGisVew:: OnDraw();”; 3)重载“CGisVew:: _OwnerDraw(MyDc myDC);”函数;

a)在头文件中,加入

“virtual void _OwnerDraw(MyDC myDC);”

b)在.cpp文件中,具体实现

“void C*View::_OwnerDraw(MyDC myDC)”

第七讲 图形编辑、类库和控件开发

1.图形编辑开发概要

MAPGIS平台的二次开发根据用户的工作需求和复杂程度提供三种不同的开发方案。 1)基本API函数开发:MAPGIS以标准c的接口形式,封装了MAPGIS所有的基本数

据结构和功能函数;这种方法功能最强,应用环境也最广,但是相对而言,编程量也最多。

2)类库(MFC)开发:这种方法主要是针对VC开发的用户,因为MAPGIS是用VC++开发出来的平台,因此对于图形显示和编辑用MFC派生了几个视类对象,封装了MAPCAD的绝大部分功能。利用这些基本视类可以快速高效地实现编辑功能,而且在此基础上还能灵活地增加自己特定的功能,编程量较少。

3)控件开发:这是一种更高和更通用的应用接口,使得在可视化程度很高的开发环境下(例VB 和DELPHI)进行二次开发更加方便和简单。

2.图形编辑API函数开发

MAPGIS图形编辑函数是运用面向对象技术开发的API函数库。在这个函数库中,我们提供了MAPGIS图形编辑系统的所有功能函数,用户可以应用这个函数库开发一个完整图形编辑系统,也可以在自己开发的应用系统中添加MAPGIS的编辑功能。

MAPGIS图形编辑函数库是一个Windows动态连接库,库中所有函数均按C标准命名方式命名,函数的原型说明在mapedit.h中。

2.1基本概念及初始化

MAPGIS图形编辑函数库是基于面向对象技术的函数库,它将窗口和编辑方法封装在一起,形成了编辑窗口对象(EDITWND)。所有的编辑功能都是基于编辑窗口对象(EDITWND)的。

由于编辑功能大都需要根据鼠标和键盘消息进行,所以用户需要将鼠标和键盘的消息传送给EDITWND。因此,使用编辑函数库时必须正确设置和使用以下几个函数。

2.2基本消息处理函数

以下九个函数是图形编辑函数库的基本函数,必须在相应的位置使用这些函数进行初始化工作,其它相应的编辑功能函数才能正常工作。从第二节开始的所有二百四十多个功能函数相应完成MAPGIS编辑系统的二百四十多项功能,您只要象下面的示例程序一样,在您需要的时候调用各功能函数就能完成您所需要的功能。函数详细说明见二次开发手册第七章。

1)_CreatEditWindow

2)_DeleteEditWindow 3)_CloseEditWindow 4)_edProcCommand 5)_edProcMouse 6)_edProcKey 7)_edProcPaint 8)_edProcSize 9)_edProcTimer

2.3示列

见二次开发手册271面例子。

3.MAPGIS类库开发

3.1 类库结构介绍

MAPGIS二次开发类库是建立在MAPGIS API之上的一个类库层,用于支持基于MFC类库的面向对象的Windows程序设计。MAPGIS二次开发类库,提供了一套强有力的C++类,它屏蔽了基于MAPGIS API之上开发MAPGIS 实用程序的许多复杂性,同时仍然允许有经验的程序员使用底层的MAPGIS API功能。如何有效地使用这个类库,且看下面介绍。

CView CGisView CGisEditView CPrjEditView CListView

CListVewEx CPrjListView CGisView类继承了Visual C++的CView类,它封装了窗口管理的各种功能及操作,它管理了窗口的图形显示参数、操作状态,滚动条的位置、范围等基本窗口属性,以及放大窗口、缩小窗口、移动窗口、显示范围、显示比例、坐标转换等功能。CGisView 类还支持窗口的保护和快速恢复等功能。CGisView类是MAPGIS类库中大多数类的基类。

CGisEditView 类继承了CGisView 类。它封装了MAPGIS编辑处理的基本数据对象和方法。包括几乎所有的点、线、区的编辑功能以及图层的处理函数、矢量化函数、节点平差函数、数字化函数、最基本的文件操作功能。CGisEditView类及其基类组成了十分强大的图形编辑函数库。

用户开发自己的软件时最好是继承CGisEditView类,这样用户可以同时使用BaseEditWindow 、CGisView 、CGisEditView类及VC++的Cview类所提供的所有功能。

CPrjEditView类继承了CGisEditView 类,它集成了对工程文件进行编辑处理所必需的数据对象的方法,具有对整个工程文件的各个文件编辑处理功能。

CPrjListView类继承了CListView 类,它是CListView的派生类,它集成了对工程文件进行控制处理所必需的数据对象的方法,具有对整个工程文件内容及各个文件状态的处理功能。

3.2 类库开发示例

使用VC++开发MAPGIS应用程序的最快速有效的方法就是使用MAPGIS类库。这些类已经为用户的程序与MAPGIS操作平台的接口做好了准备,用户可以体会到使用这些类可以很容易地实现MAPGIS系统里的功能,而且在实现MAPGIS系统功能的基础上用户还可以随意地添加自己想要的功能。下面我们以CGisEditView类为例讲述如何构造一个简单的MAPGIS图形编辑器的方法和基本步骤。

第一步、建一个Visual C++的项目。打开Visual C++工作环境,选择File菜单New命令,在弹出的对话框中选择Projects页的MFC AppWizard(EXE)项并在Project name编辑框中敲入工程名(例如:engineer),然后单击OK。这样便进入了AppWizard(向导)的第一步,在这一步里用户要选择工程类型,可以选择单文档或多文档工程(基于对话框的工程不适合我们建MAPGIS工程),初学者最好选单文档类型;单击Next进入向导的第二步、第三步、直到完成(Finish之后OK),这几步用户可以采用默认设置。到此为止一个VC的项目已建好,然后用户的工作就是在这个项目中实现MAPGIS平台中的功能及自己想要的其他功能。

第二步、包含MAPGIS头文件 #include “MAPGIS.h”,最好是加在STDAFX.H头文件中,这样我们只需要加入一次头文件;当然,你也可以在用到MAPGIS的时候加入此头文件。 第三步、要完成的工作是将工程中的视图类的基类改为CGisEditView类。具体操作是打开工程中的视图类的两个文件(*View.h、*View.cpp),用Visual C++查找替换功能(Edit菜单下的Rplace命令或热键Ctrl+H)分别将这两个文件中的CView字符串全部替换为CGisEditView,

第四步、在视类的OnDraw()函数中调用CGisEditView类中的OnDraw(pDC)函数,以完成绘图工作的预先处理。具体操作方法:在视图类的OnDraw(CDC* pDC)函数中加语句CGisEditView::OnDraw(pDC)。见下面示例:

void CEngineerView::OnDraw(CDC* pDC)

{

CEngineerDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc); // TODO: add draw code for native data here CGisEditView::OnDraw(pDC);

}

第五步、在视类中增加显示成员函数:DispAllMap(MyDC mdc);见下面示例: void CEngineerView::DispAllMap(MyDC mdc) { //在此处做所有的图形显示工作 }

第六步、在视类中增加背景绘制成员函数:DrawBackground (MyDC mdc);在这个函数中可以对窗口的背景进行渲染、绘制;见下面示例:

void CEngineerView:: DrawBackground (MyDC mdc)

{ }

3.3 CGisView类概述

CGisView类继承了Visual C++的CView类,它封装了与图形显示有关的操作,如放大窗口、缩小窗口、移动窗口、显示范围、显示比例、坐标转换、闪烁图元等功能。

文件说明

说明头文件: mapgissdk60\\include\\CGisView.h

连接静态库: mapgissdk60\\lib\\ w60operD.lib (Debug版本)

mapgissdk60\\lib\\ w60oper.lib (Release版本)

执行动态库: mapgissdk60\\dll\\ w60operD.dll (Debug版本) mapgissdk60\\dll\\ w60oper.dll (Release版本) 3.4 CGisEditView类概述

CGisEditView类继承了CGisView 类和BaseEditWindow类,它封装了几乎所有的点、线、区的编辑功能以及图层的处理函数、矢量化函数、数字化函数。CGisEditView类及其基类组成了十分强大的图形编辑函数库。

使用CGisEditView类 首先,用Visual C++新建一个项目,项目中的视图类必须继承CGisEditView类(可以

//在此处做窗口背景的绘制

用Visual C++查找替换的功能来完成,替换完不要忘记#include “cgisedit.h”)。 第二步,在视图类的OnDraw(CDC* pDC)函数中加语句CGisEditView::OnDraw(pDC); 在OnDraw(CDC* pDC)函数中就不必再做其他处理。

第三步,在视图类中必须添加成员函数void _OwnerDraw(MyDC mydc);因为在MapGis系统中的图形显示是在_OwnerDraw(MyDC mydc)函数中完成的,而不是在OnDraw(CDC* pDC)函数中完成。用户可以在_OwnerDraw(MyDC mydc)函数中完成自己的图形显示工作,但建议用户最好还是调用基类中的_OwnerDraw(MyDC mydc)函数,它会自动完成点、线、区的显示;当然用户也可以在调用_OwnerDraw(MyDC mydc)函数的基础上再添加自己的显示语句。 第四步,在VC的workspace窗口FileView标签中加入MapGis二次所需的.Lib库文件。 完成这几步用户就可以随意地使用CGisEditView类及其基类中的函数设计自己的图形软件了。 文件说明

说明头文件: mapgissdk60\\include\\CGisEdit.h

连接静态库: mapgissdk60\\lib\\ maped6D.lib (Debug版本) mapgissdk60\\lib\\ maped60.lib (Release版本) 执行动态库: mapgissdk60\\dll\\ maped6D.dll (Debug版本)

mapgissdk60\\dll\\ maped60.dll (Release版本)

3.5 CPrjEditView类概述

CPrjEditView类继承了CGisEditView 类,它是CGisEditView的派生类,它集成了对工程文件进行编辑处理所必需的数据对象的方法,具有对整个工程文件中各个工作区的编辑处理功能。

文件说明

说明头文件: mapgissdk60\\include\\CPrjEdit.h

连接静态库: mapgissdk60\\lib\\ maped6D.lib (Debug版本) mapgissdk60\\lib\\ maped60.lib (Release版本) 执行动态库: mapgissdk60\\dll\\ maped6D.dll (Debug版本)

mapgissdk60\\dll\\ maped60.dll (Release版本)

3.6 CPrjListView类概述

CPrjListView类继承了CListView 类,它是CListView的派生类,它集成了对工程文件进行控制处理所必需的数据对象的方法,具有对整个工程文件内容及各个文件状态的处理功能

他类似于Visual C++的WorkSpace管理器,负责添加/删除/修改工程中各项目的内容,并实现与工程相关的一些操作和处理。他和CPrjEditView联合起来使用,公共一个MAPPROJECT数据源,可实现工程的所有管理和显示/编辑的功能。

利用CPrjListView和CPrjEditView可快速搭建VC环境下的MAPGIS编辑框架和实现其功能(例:MAPGIS编辑器就是此两类实现的),利用CPrjListView和CPrjEditView其对应的控件也可在VB或Delphi等可视化程度更高的开发环境下更高效地实现MAPGIS的编辑功能。

文件说明

说明头文件: mapgissdk60\\include\\PrjListView.h

连接静态库: mapgissdk60\\lib\\ PrjVw60D.lib (Debug版本) mapgissdk60\\lib\\ PrjVw60.lib (Release版本) 执行动态库: mapgissdk60\\dll\\ PrjVw60D.dll (Debug版本) mapgissdk60\\dll\\ PrjVw60.dll (Release版本)

4.MAPGIS控件开发

4.1 控件结构介绍

MAPGIS基于控件的应用程序开发是MAPGIS提供的一种更加快速和高效的开发方法。MAPGIS提供了一整套强有力的控件支持,范围从工程的编辑,工程的输出到工程的管理。且看下面介绍。

1)工程编辑和输出控件

文件: ActxEdit.OCX 控件: GisEdit 文件: GisCtrl.OCX 控件: MapGisCtrl

2)工程管理控件

控件: MapProjectOut 控件 MapPublishOut 控件: MapRastOut

文件: PrjList.OCX 控件: PrjList 3)属性编辑控件

文件: EditGisAtt.OCX 控件: EditGisAtt

MAPGISCTRL控件是MAPGIS中基本的图形显示控件,与工作区显示有关的控件是以他为基础继承而来的。

GISEDIT控件是MAPGIS基本的工程图形编辑控件,是由MAPGISCTRL控件派生而来的,其数据基础是工程对象。它封装了最基本的文件操作功能、线编辑功能、区编辑功能、点编辑功能、图层处理函数、库编辑函数、矢量化、节点平差等函数。它集成了MAPGIS编辑处理的基本数据对象和方法。

MAPPROJECTOUT / MAPPUBLISHOUT / MAPRASTOUT控件是MAPGIS基本的工程图形输出控

件,是由MAPGISCTRL控件派生而来的。它们封装了最基本的输出操作功能,针对不同的输出文件类型它又分为a.MapProjectOut——对工程文件(*.mpj)的输出处理;b.MapPublishOut ——对拼版文件(*.mpb)的输出处理;c. MapRastOut ——对光栅类文件(*.nv1)的输出处理。

PRJLIST控件是MAPGIS基本的工程管理控件,它集成了对工程文件进行控制处理所必需的数据对象的方法,具有对整个工程文件内容及各个文件状态控制的功能。

EDITGISATT控件是MAPGIS基本的属性编辑控件,它可以对工作区中实体的属性进行编辑和修改。

4.2 使用MAPGIS控件开发应用程序

使用可视化程度很高的开发工具VB ,Delphi等开发MAPGIS应用程序的最快速有效的方法就是使用MAPGIS控件。这些控件已经为用户的程序与MAPGIS操作平台的接口做好了准备,用户可以体会到使用这些控件可以很容易地实现MAPGIS系统里的功能。下面我们以ACTXEDIT控件和PRJLIST控件为例讲述在Visual Basic开发环境下如何构造一个简单的MAPGIS图形编辑器的方法和基本步骤。

例子见二次开发手册14.1.1节(P524)。 4.3 开发的数据组织和结构设计

1)数据的组织

图形编辑地二次开发地数据对象除了基本地点线面文件,用地比较多地还有工程文件数据.

2)结构的设计

(a)以单个文件为处理对象地情况(以CGisEditView为开发基本视类)

基本数据文件(点/线/面和 光栅文件) 文件处理 CGisEditView处理,实现平 台的基本编辑功能

派生 SetExtTool CMyEditTool集合 功能1…交互/处理 CMyEditView为实现自己的功能2…交互/处理 处理功能提供桥梁 功能3…交互/处理

…… 自己的处理在此实现,通

其它的辅助功能和设置 过SetExtTool()

(b)工程文件为处理对象地情况(以CPrjEditView为开发基本视类)本例采用VC的文档与视的结构体系,一个工程数据对应两种不同的表现和交互方式:工程列表管理和图形显示.其中工程列表管理主要控制工程文件中的不同图层文件的状态和存在;图形显示主要是对各个图层文件中的所有图元的空间数据和属性数据进行管理.它们公用一个数据源—“工程文件”,它保存在文档中.

它们之间的结构示意图:

(c) 控件开发(以编辑控件GisEdit和PrjList为例)本例采用工程数据为处理对象.

3) MFC开发与控件开发之间的结构关系对应图

用户的工程操作 CMyEditTool集合 功能1…交互/处理 功能2…交互/处理 功能3…交互/处理 …… 自己的处理在此实现,通过SetExtTool() 交互操作 SetExtTool 派生 CMyPrjListView为工程管理交互提供接口 派生 SetTxtToo工程数据文件(包括点/线/面和图象文件) 文件处理 CPrjListView处理基本的工程数据管理 CPrjEditView处理,实现平台的基本编辑功能 CMyPrjEditView为图形交互和功能处理提供接口 工程数据文件 GisEdit控件(包括属性/方法/事件) 在GisEdit的鼠标处理事件中实现自己的交互操作和功能. 在GisEdit的EditOperator事件中切换操作状态 PrjList控件(包括属性/方法/事件) 无论是MFC开发还是控件开发,他们的分层结构都有较好的对应关系。

CPrjListView视类 PrjList控件 CPrjEditView视类 MFC开发方案

控件开发方案

对应 CGisView视类 派生 CGisEditView视类 GisEdit控件 MapGisCtrl控件 派生 MpOutClr.ocx MapProjectOut控件MapPublishOut控件MapRastOut控件 属性操作API函数 EditGisAtt控件 第八讲 矢量空间分析和属性查询

1.矢量空间分析

迭加分析:包括区对区迭加分析、线对区迭加分析、点对区迭加分析、区对点迭加分析和点对线迭加分析。

缓冲区分析:包括点BUFFER分析、线BUFFER分析、区BUFFER分析。 设有原文件A和B,迭加结果为文件C,其中: A文件属性为: 缺省字段, f1 B文件属性为: 缺省字段, f2

缺省字段随着图形类型的不同而不同,分别是: 点文件:标志码。

线文件:标志码、线长度。 区文件:标志码、面积、周长。 迭加过程如下图所示:

文件A(A图形和A属性) 文件B(B图形和B属性)

文件C(C图形和C属性) 其中C文件的图形类型和A文件相同,而属性则是A文件与B文件属性连接的结果。

1.1迭加分析

(a) 区对区迭加分析

包括合并、相交、相减、判别四种方式。迭加结果用限影表示,迭加结果的属性为: 标志码、面积、周长,f1、区号、f2

其中区号为第二个文件的区号。

合并:属于A或属于B的区域。

标志码 面积 周长 f1 标志码 面积 周长 f2 标志码 面积 周长 f1 区号 F2 1 320.5 61.2 a

1 280.7 50.1 b 1 2 3 198.2 51.3 a 122.3 42.1 a 158.4 53.4 1 1 b b

相交:属于A且属于B的区域。

1

320.5 61.2 a

1 280.7 50.1 b

1 122.3 42.1 A

标志码 面积 周长 f1 标志码 面积 周长 f2 标志码 面积 周长 F1 区号 f2 1 b

相减:属于A不属于B的区域。

标志码 面积 周长 f1 标志码 面积 周长 f2 标志码 面积 周长 F1 区号 F2 1

320.5 61.2 a

1 280.7 50.1 b

1 198.2 51.3 A

判别:属于A的区域。

标志码 面积 周长 f1 标志码 面积 周长 f2 标志码 面积 周长 f1 区号 F2 1 320.5 61.2 a 1 280.7 50.1 b 1 2 198.2 51.3 a b 122.3 42.1 a 1

(b) 线对区迭加分析

包括相交、判别、相减三两种方式,迭加结果文件仍然是线文件,迭加结果的属性为:

标志码、线长度、f1、区号、f2

线图元用标号表示。 相交:穿过区域的线段部分

标志码 线长度 f1 标志码 面积 周长 f2 1 167.0 a

1 320.5 61.2 b 标志码 线长度 f1 区号 f2

1 80.8 a 1 b

判别:所有线图元

标志码 线长度 f1 标志码 面积 周长 f2 1

167.0 a

1 320.5 61.2 b 标志码 线长度 F1 区号 f2 1 2 3 32.2 a 80.8 A 44.0 A 1 b

相减:区域以外的线段

标志码 线长度 f1 标志码 面积 周长 f2 1 167.0 a

1 320.5 61.2 b 标志码 线长度 f1

1 3 32.2 44.0 a a

(c) 点对区迭加分析

包括相交、判别、相减三种方式,迭加结果文件仍然是点文件,结果属性为:

本文来源:https://www.bwwdw.com/article/w4l3.html

Top