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);
在實現檔案中實現此兩個函式
兩個轉換函式中用到的成員變數在檢視類中定義:
float m_xStart,m_yStart,blc; //繪製圖形時的起點座標和比例尺
int m_hScreen,m_wScreen; //當前檢視的高度和寬度
int m_MapMode; //映像模式
在檢視類的建構函式中完成初始化:
m_xStart=0;
m_yStart=0;
blc=1.0;
m_MapMode=1; //映像模式初始化
成員變數
為檢視類新增訊息處理函式OnSize();
//當檢視的大小變化時被呼叫,cx,cy為變化後螢幕頂長、寬(畫素)
為了在應用程式的其他類中能夠使用這兩個座標函式,可以定義兩個全域性函式來實現轉換操作功能。在實現檔案【Drawdoc.cpp】中定義兩個全域性函式如下:
//全域性函式,座標轉換,為了能在檢視類中使用
void DPtoVP(float x,float y,int *X,int *Y);
void VPtoDP(int x,int y,float *X,float *Y);
還是在實現檔案【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);
}
以上兩個全域性函式利用檢視類指標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;
在檢視類的過載虛擬函式【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);
}
2、實現各圖形元素類的繪製函式
利用虛擬函式來實現各種圖形元素的繪製功能。在圖形元素基類CDraw中,抽象定義一個進行繪製的虛擬函式。因為不需要用【CDraw】類直接來定義物件,所以可以將虛擬函式定義成純虛擬函式。
virtual void Draw(CDC *pDC,int m_DrawMode,int m_DrawMode1,short BackColor)=0;
引數說明:
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直線的繪製
在直線類的實現程式碼中,加入過載函式的實現程式碼:
3.2 連續直線和多邊形區域的繪製
3.3 圓和填充圓的繪製
3.4 圓弧的繪製
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);
在實現函式中加入這個函式的實現程式碼:
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);
}
}
以上函式實現了對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);
}
在OnDraw函式中,呼叫了文件類的Draw函式來繪製所有的圖形元素。
CBrush brush(p_GraphPara->GetColor(m_bColor)); 這個函式呼叫的文件類中CGraphPara類的成員函式,
所以需要在檢視類的實現檔案中新增外部引用。
參考資料:陳建春,Visual C++開發GIS系統--開發例項剖析。
地理資訊科學
Writed By NX
QQ:1051926720