GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

GIS程序设计(七)实现基本矢量图形系统的文档和视图(3

实现矢量图形系统的视图

本节将在上两节的基础之上,实现矢量图形系统的视图,完成矢量图形系统的图形元素绘制功能。

1、建立坐标系

在组织一幅图形时,采用哪一种映像方式组织矢量图形系统的坐标系值得进行研究。在本矢量图形系统中,可以建立一个坐标原点在左下角的坐标系,然后建立这个坐标系和Windows各个坐标系映像方式之间的转换关系。在此坐标系中,取左下角为原点,给定这个点的实际坐标为(m_xStart,m_yStart,并确定一个变量blc,作为逻辑坐标和实际坐标的比例关系。

为了实现实际坐标和逻辑坐标之间的转换,在视图类【CDrawView】中定义如下的两个转换函数:

public:

void DPtoVP(float x,float y,int *X,int *Y);

void VPtoDP(int x,int y,float *X,float *Y);

在实现文件中实现此两个函数

GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

两个转换函数中用到的成员变量在视图类中定义:

float m_xStart,m_yStart,blc; //绘制图形时的起点坐标和比例尺

int m_hScreen,m_wScreen; //当前视图的高度和宽度

int m_MapMode; //映像模式

 GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

在视图类的构造函数中完成初始化:

m_xStart=0;

m_yStart=0;

blc=1.0;

m_MapMode=1; //映像模式初始化

 GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

成员变量m_hScreen,m_wScreen在消息处理函数OnSize中初始化,当窗口创建或窗口大小发生变化时,OnSize消息处理函数被调用。

为视图类添加消息处理函数OnSize();

 GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

//当视图的大小变化时被调用,cx,cy为变化后屏幕顶长、宽(像素)

 GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

为了在应用程序的其他类中能够使用这两个坐标函数,可以定义两个全局函数来实现转换操作功能。在实现文件【Drawdoc.cpp】中定义两个全局函数如下:

//全局函数,坐标转换,为了能在视图类中使用

void DPtoVP(float x,float y,int *X,int *Y);

void VPtoDP(int x,int y,float *X,float *Y);

 GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

还是在实现文件【Drawdoc.cpp】中加入这两个函数的实现代码:

void DPtoVP(float x,float y,int *X,int *Y)

{

p_View->DPtoVP(x,y,X,Y);

}

 

void VPtoDP(int x,int y,float *X,float *Y)

{

p_View->VPtoDP(x,y,X,Y);

}

 GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

以上两个全局函数利用视图类指针p_View调用视图类的两个坐标转换函数,来完成坐标的转换操作功能。如果要在某个实现文件中使用这两个全局函数,只需在这个实现文件的开始处加入全局函数的外部引用

extern void DPtoVP(float x,float y,int *X,int *Y);

extern void VPtoDP(int x,int y,float *X,float *Y);

在以上的两个全局函数中,p_View指向当前**的视图对象。p_View是一个在实现文件【Drawview.cpp】中全局定义的视图类指针:

CDrawView *p_View;

 GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

在视图类的重载虚函数【OnActiveView】中,对p_View指针进行初始化,以保证p_View指针时刻指向当前**的视图对象:

void CDrawView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView)

{

// TODO: Add your specialized code here and/or call the base class

p_View = this;

CView::OnActivateView(bActivate, pActivateView, pDeactiveView);

}

 GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

2、实现各图形元素类的绘制函数

利用虚函数来实现各种图形元素的绘制功能。在图形元素基类CDraw中,抽象定义一个进行绘制的虚函数。因为不需要用【CDraw】类直接来定义对象,所以可以将虚函数定义成纯虚函数。

virtual void Draw(CDC *pDC,int m_DrawMode,int m_DrawMode1,short BackColor)=0;

 GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

参数说明:

pDC:指向当前绘图对象的指针

m_DrawMode:绘制模式 1-R2_COPYPEN 2-R2_NOT

m_DrawMode1: 直线绘制方式。0-正常显示 1-特殊显示 2-用指定颜色绘制

在各种图形元素类中,重载虚函数。

virtual void Draw(CDC *pDC,int m_DrawMode,int m_DrawMode1,short BackColor);

3.1直线的绘制

在直线类的实现代码中,加入重载函数的实现代码:

GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

3.2 连续直线和多边形区域的绘制

GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

3.3 圆和填充圆的绘制

GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

3.4 圆弧的绘制

GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

 

3.5 标注文本的绘制

IMPLEMENT_SERIAL(CText,CObject,1)

void CText::Draw(CDC *pDC,int m_DrawMode,int m_DrawMode1,short BackColor)

{         

if(b_Delete) //如果已经处于删除状态

return;

short ColorPen=m_ColorPen;

if(m_DrawMode1==2) //指定颜色绘制

ColorPen=BackColor;

CFont cjcf;  //定义一个字模

int high,wide,cc1,cc2,cd,angg;

unsigned char c1,c2;

float x1,y1,ang1;

char bz[4];

const char *ls1;

if(m_DrawMode==0)

pDC->SetROP2(R2_COPYPEN);

else if(m_DrawMode==1)

pDC->SetROP2(R2_NOT);  

pDC->SetBkMode(TRANSPARENT);

high=DLtoVL(m_TextHeight); //得到字体的点阵高度

ang1=(float)(m_Angle1*pi/180);

if(high<3||high>200)

return;                 //字体太小或太大将不显示

x1=m_StartX-m_TextHeight*(float)sin(ang1);

y1=m_StartY+m_TextHeight*(float)cos(ang1);

angg=(int)(m_Angle2*10);

wide=DLtoVL(m_TextWide);

//起始点的屏幕点阵坐标

DPtoVP(x1,y1,&cc1,&cc2);

//创建字模

cjcf.CreateFont(high,wide,angg,0,50,0,0,0,255,OUT_TT_PRECIS,CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,FIXED_PITCH,"cjc");

//选中字模

CFont* cjcbakf=pDC->SelectObject(&cjcf);

pDC->SetBkMode(TRANSPARENT);          //设定显示方式

pDC->SetTextColor(p_GraphPara->GetColor(ColorPen)); //设定文本颜色

ls1=(const char *)c_Text;                     //文本内容

cd=strlen(ls1);                       //文本字符长度

while(cd>0)  //绘出所有的字符

{

c1=*ls1;

c2=*(ls1+1);

if(c1>127&&c2>127)  //如果是一个汉字

{

strncpy(bz,ls1,2);//拷贝一个汉字到bz

bz[2]=0;

ls1=ls1+2;        //跳过汉字指向下一个字符位置

pDC->TextOut(cc1,cc2,bz); //在屏幕上写这个汉字

cd=cd-2;                  //字符数减2

//下一个字符的显示位置

x1=x1+(m_TextWide*2+m_OffWide)*(float)cos(ang1);

y1=y1+(m_TextWide*2+m_OffWide)*(float)sin(ang1);

//下一个字符显示位置的屏幕坐标

DPtoVP(x1,y1,&cc1,&cc2);

}

else //如果是一个西文字符

{

strncpy(bz,ls1,1);       //拷贝一个字符到bz

bz[1]=0;

ls1++;                   //跳过这一个字符到下一个字符

pDC->TextOut(cc1,cc2,bz);//在屏幕上写字符

cd=cd-1;                 //字符数减1

//下一个字符的显示位置的实际坐标

 

x1=x1+(m_TextWide+m_OffWide/2)*(float)cos(ang1);

y1=y1+(m_TextWide+m_OffWide/2)*(float)sin(ang1);

//下一个字符显示位置的屏幕坐标

DPtoVP(x1,y1,&cc1,&cc2);

}

}

pDC->SelectObject(cjcbakf);//恢复字模

}

4、视图类的OnDraw函数。实现视图

为了实现应用程序的图形绘制工作,在文档类【CDrawDoc】中定义一个函数如下:

void Draw(CDC *pDC,int m_DrawMode,int m_DrawMode1,short BackColor);

 GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

在实现函数中加入这个函数的实现代码:

void CDrawDoc::Draw(CDC *pDC,int m_DrawMode,int m_DrawMode1,short BackColor)

{

  for(int i=1; i<=5 ; i++)

  {

    int nn = GetGraphUpperBound(i)+1;

while(nn--)

      GetGraph(i,nn)->Draw(pDC,m_DrawMode, m_DrawMode1, BackColor);

  }

}

 GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

 

以上函数实现了对5中图形元素的绘制工作。对于每一类图形元素,绘制过程如下:

①调用GetGraphUpperBound()函数,得到存储这类图形元素对象指针的最大数组下标、

②对所有的图形元素循环,得到指向每一个图形元素对象的指针。然后通过这个指针调用图形元素类的Draw函数实现图形元素的绘制操作。

 

1、为了实现图形元素在视图中的绘制,对视图类的OnDraw函数进行修改,修改后的OnDraw函数实现代码如下:

void CDrawView::OnDraw(CDC* pDC)

{

CDrawDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

CBrush brush(p_GraphPara->GetColor(m_bColor));  //创建CBrush对象

    CBrush* pOldBrush = pDC->SelectObject(&brush);  //将画刷选入绘图对象

pDC->PatBlt(0,0,m_wScreen,m_hScreen,PATCOPY);   //用画刷填充视图区域

pDC->SelectObject(pOldBrush);   //恢复原来的画刷

pDoc->Draw(pDC,0,0,m_bColor);

}

 GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

OnDraw函数中,调用了文档类的Draw函数来绘制所有的图形元素。

CBrush brush(p_GraphPara->GetColor(m_bColor));  这个函数调用的文档类中CGraphPara类的成员函数,

所以需要在视图类的实现文件中添加外部引用。

 GIS程序设计(七)实现基本矢量图形系统的文档和视图(3) 实现矢量图形系统的视图

参考资料:陈建春,Visual C++开发GIS系统--开发实例剖析。

地理信息科学

Writed By NX

QQ:1051926720