计算机地图制图 上机实验指导书 康 建 荣 2010 年 10 月
实验内容 在 VC 开发环境下, 编制绘制世界地图程序 一 实验步骤 1. 建立工程 DrawProjection (1) 选择文件菜单下的 New 命令, 如图 1 所示 工程名 :DrawProjection 选择工程目录路径 图 2.2 新建工程 (2) 从 New 对话框中选择 Project 选项卡 在 Project name 处输入工程名, 一般来说, 工程的命名在一定程度上是任意的, 这里我们假定工程名为 DrawProjection, 在 Location 处输入保存工程的文件夹 然后在左边的列表中确信选择了 MFC AppWizard (exe), 在 Platform 列表中确信选择了 Win32 完成之后单击 OK 进入下一步 (3) 在 AppWizard 新建程序的第一步 ( 如图 2) 中在 Application Type 选择时选择 Single document 即可 1
图 2 建立单文档界面程序 :Step1 (4) 在第二步 ( 如图 3 所示 ) 中, 由于我们现在建立的只是简单的单文档程序, 我们选择不需要任何数据库支持 图 3 建立单文档界面程序 Step 2 (5) 在第三步 ( 如图 4 所示 ) 中, 我们将设定生成的标准程序中的文档支持 AppWizard 提供有容器类 (Container) 与服务类 (Server) 应用, 我们保持缺省设置 ( 不需要容器类与服务类支持, 但保留 ActiveX Control 控件支持 ) 2
图 4 建立单文档界面程序 Step 3 (6) 在第四步 ( 如图 5) 中, 我们去除掉打印预览及打印支持 但我们保持工具条, 状态条, 三维控制支持 对刚使用的文件列表数设置为四 图 5 建立单文档界面程序 Step 4 (7) 在第五步 ( 如图 6) 中, 我们将设定是否设置提示及怎样使用 MFC 库 在刚开始时, 我们设定需要提示, 同时, 动态链接 MFC 库 3
图 6 建立单文档界面程序 Step 5 (8) 在最后一步中 ( 如图 7) 中, 我们将设定 AppWizard 将要为我们生成的类 图 7 建立单文档界面程序 Step 6 这样, 我们就建立起一个具有 Document/View 结构的简单的应用程序 2. 增加新类 (1) 类 :CShape 方法 : 4
图 8 增加类界面 (a) 在图 8 所示情况下, 鼠标左键点击类视图, 出现如图所示情形, 选中 DrawProjection classes 后点右键, 出现弹出式菜单, 然后选择 New Class 项 (b) 出现图 9 所示对话框后, 在 Class type 项中选择 Generic Class, 在 Name 项中键 图 9 增加类对话框 5
入 CShape, 在 Base class(es) 项中键入 CObject, 然后点击 OK 这样就新增加了类名 (c) 在 CShape 类的头文件中增加内容 在类视图中双击类名 CShape 即进入类定义头文件 增加后完整的内容如下 : // Shape.h: interface for the CShape class. // ////////////////////////////////////////////////////////////////////// #if!defined(afx_shape_h D3ED0500_AEF7_11D7_A6BC_00A0CCCF0ED3 INCLUDED_) #define AFX_SHAPE_H D3ED0500_AEF7_11D7_A6BC_00A0CCCF0ED3 INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "math.h" #define MAXPOINTS 35000 typedef struct double x; double y; Bpoint; typedef struct long PtNo; double hzz; Bpoint *Pt; int bz; Spline; class CShape : public CObject protected: CShape(); DECLARE_SERIAL(CShape) //Attributes protected: COLORREF m_color;// 线的颜色 UINT m_npenwidth;// 线宽 public: BOOL m_bdelete; int m_sort;// 图形类别 : 直线 :0; 矩形 :1; 圆 :2; 文本 :3; 多义线 :4 CRect m_rectbounding;// 图形元素的最小包围框 public: CRect& GetBoundingRect()return m_rectbounding;// 取得包围框 //Operations 6
public: BOOL IsLine()return (this->m_sort==0);;// 判断是否直线 BOOL IsPline()return (this->m_sort==1);;// 判断是否多义线 BOOL IsRect()return (this->m_sort==3);;// 判断是否点 BOOL IsPoint()return (this->m_sort==2);;// 判断是矩形 BOOL IsText()return (this->m_sort==4);;// 判断是否文本 BOOL IsTIN()return (this->m_sort==5);;// 判断是否 TIN BOOL IsBSpline()return (this->m_sort==6);;// 判断是否 B 样条曲线 BOOL IsZSpline()return (this->m_sort==7);;// 判断是否张力样条曲线 virtual BOOL Draw(CDC* pdc,double xmin,double xmax,double ymin,double ymax,double blc,colorref cr,int type);// 绘制图形 virtual void FinishShape();// 计算包围框 void SetPenAttr(UINT penw,colorref color);// 设置画笔属性 void SetDrawSort(int kind)// 设置当前图形类别 this->m_sort=kind; public: double CalDisp(double x1, double y1, double x2, double y2); double PointLine(double xx, double yy, double x1, double y1, double x2, double y2); BOOL PointRgn(float x,float y,int Numble,double *XX,double *YY,float blc); virtual void OffsetPoint(CPoint &p);// 偏移图形元素位置 virtual void Serialize(CArchive &ar);// 保存元素 ; #endif //!defined(afx_shape_h D3ED0500_AEF7_11D7_A6BC_00A0CCCF0ED3 INCLUDED_) (d) 完成 CShape 类中各成员函数的定义, 完整的内容如下 : // Shape.cpp: implementation of the CShape class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Shape.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]= FILE ; #define new DEBUG_NEW #endif #ifndef M_PI #define M_PI 3.1415926535897 #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// IMPLEMENT_SERIAL(CShape, CObject, 2) 7
CShape::CShape() m_rectbounding.setrectempty(); this->m_npenwidth=1; this->m_color=rgb(0,0,0); void CShape::SetPenAttr(UINT penw,colorref color) this->m_npenwidth=penw; this->m_color=color; void CShape::FinishShape() return; void CShape::Serialize(CArchive &ar) if(ar.isstoring()) ar<<m_rectbounding; ar<<(word)m_npenwidth; ar<<m_color; ar<<m_sort; ar>>m_rectbounding; WORD w; ar>>w; m_npenwidth=w; ar>>m_color; ar>>m_sort; BOOL CShape::Draw(CDC *pdc,double xmin,double xmax,double ymin,double ymax,double blc,colorref cr,int type) return TRUE; void CShape::OffsetPoint(CPoint &p) return; double CShape::PointLine(double xx, double yy, double x1, double y1, double x2, double y2) 8
double aa,bb,cc,ang1,ang2,ang; // 计算三条边的距离 aa=caldisp(x1,y1,xx,yy); if(aa==0.0) return 0.0; bb=caldisp(x2,y2,xx,yy); if(bb==0.0) return 0.0; cc=caldisp(x1,y1,x2,y2); // 如果 (x1,y1) 和 (x2,y2) 是一个点, 即线段是一个点, 退出函数并返回距离 if(cc==0.0) return aa; if(aa<bb)// 如果 (xx,yy) 到 (x1,y1) 的这条边较短 if(y1==y2) if(x1<x2) ang1=0.0; ang1=m_pi;//pi ang1=acos((x2-x1)/cc); if(y1>y2) ang1=2.0*m_pi-ang1;// 直线 (x1,y1)->(x2,y2) 斜率的弧度 ang2=acos((xx-x1)/aa); if(y1>yy) ang2=2.0*m_pi-ang2;// 直线 (x1,y1)->(xx,yy) 斜率的弧度 ang=ang2-ang1; if(ang<0.0) ang=-ang; if(ang>m_pi) ang=2.0*m_pi-ang;// 交角的大小 if(ang>0.5*m_pi) return aa;// 如果为钝角, 直接返回距离 return(aa*sin(ang));// 否则返回计算得到的距离 // 如果 (xx,yy) 到 (x2,y2) 的这条边较短 if(y1==y2) if(x1<x2) ang1=m_pi; ang1=0.0; ang1=acos((x1-x2)/cc); if(y2>y1) ang1=2.0*m_pi-ang1; ang2=acos((xx-x2)/bb); if(y2>yy) ang2=2.0*m_pi-ang2; 9
ang=ang2-ang1; if(ang<0.0) ang=-ang; if(ang>m_pi) ang=2.0*m_pi-ang; if(ang>0.5*m_pi) return bb; return(bb*sin(ang)); double CShape::CalDisp(double x1, double y1, double x2, double y2) return(sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))); // 函数 PointRgn 作用 : 判断一个点是否在任意多边形区域内 // 参数 :Numble- 边界点数,x,y 是点的坐标, 多边形顶点的坐标在结构数组 PointList 中 // 返回 :1- 点在多边形区域 0- 不在 BOOL CShape::PointRgn(float x,float y,int Numble,double *XX,double *YY,float blc) CRgn rgn; // 定义一个 CRgn 对象 int x1,y1,i; CPoint bbcc[500]; if(numble<3) return 0;// 如果点的数目 <3 即不是一个区域返回不成功标志 // 将点的坐标转变成屏幕坐标 x1=(int)(x/blc); y1=(int)(y/blc); // 将封闭区域各点的坐标转成屏幕坐标 for(i=0;i<numble;i++) bbcc[i].x=(int)((xx[i])/blc); bbcc[i].y=(int)((yy[i])/blc); rgn.createpolygonrgn(bbcc,numble,1);// 初试化一个多边形区域 i=(rgn.ptinregion(x1,y1)!=0); // 如果在区域内 j=1, 否则 j=0; rgn.deleteobject(); // 删除定义的 rgn 对象 return i; (2) 增加类 CPline 方法同上, 类的类型同上, 类的基类为 :CShape 完整的头文件和 CPP 文件如下 : // Pline.h: interface for the CPlines class. // ////////////////////////////////////////////////////////////////////// #if!defined(afx_pline_h D3ED0501_AEF7_11D7_A6BC_00A0CCCF0ED3 INCLUDED_) #define AFX_PLINE_H D3ED0501_AEF7_11D7_A6BC_00A0CCCF0ED3 INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 10
#include "Shape.h" class CPlines : public CShape DECLARE_SERIAL(CPlines) public: void GetRect(double *minx,double *miny,double *maxx,double *maxy); BOOL IsPoint(double x,double y,double jl,double blc); CPlines(); CPlines(Spline sline,uint penw,colorref color); CPlines(CPlines &sline); CPlines operator=(cplines &sline); virtual ~CPlines(); virtual BOOL Draw(CDC *pdc,double xmin,double xmax,double ymin,double ymax,double blc,colorref cr,int type); virtual void FinishShape(); virtual void OffsetPoint(CPoint &p);// 偏移图形元素位置 virtual void Serialize(CArchive &ar);// 保存元素 ; double minx0,miny0,maxx0,maxy0; Spline m_line; #endif //!defined(afx_pline_h D3ED0501_AEF7_11D7_A6BC_00A0CCCF0ED3 INCLUDED_) // Pline.cpp: implementation of the CPlines class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Pline.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]= FILE ; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// IMPLEMENT_SERIAL(CPlines,CShape,2) CPlines::CPlines() this->m_color=rgb(0,0,0); this->m_npenwidth=1; this->m_bdelete=false; 11
CPlines::~CPlines() if(m_line.pt!=null) delete []m_line.pt; CPlines::CPlines(Spline sline,uint penw,colorref color) this->m_color=color; this->m_npenwidth=penw; this->m_line.ptno=sline.ptno; this->m_line.bz=sline.bz; this->m_line.hzz=sline.hzz; int n; this->m_line.pt=new Bpoint[sLine.PtNo]; this->minx0=this->maxx0=sline.pt[0].x; this->miny0=this->maxy0=sline.pt[0].y; for(n=0;n<sline.ptno;n++) this->m_line.pt[n].x=sline.pt[n].x; this->m_line.pt[n].y=sline.pt[n].y; this->minx0=this->minx0<sline.pt[n].x?this->minx0:sline.pt[n].x; this->maxx0=this->maxx0>sline.pt[n].x?this->maxx0:sline.pt[n].x; this->miny0=this->miny0<sline.pt[n].y?this->miny0:sline.pt[n].y; this->maxy0=this->maxy0>sline.pt[n].y?this->maxy0:sline.pt[n].y; CPlines::CPlines(CPlines &sline) if(&sline!=this) this->m_color=sline.m_color; this->m_npenwidth=sline.m_npenwidth; this->m_line.ptno=sline.m_line.ptno; this->m_line.bz=sline.m_line.bz; this->m_line.hzz=sline.m_line.hzz; int n; this->m_line.pt=new Bpoint[sLine.m_line.PtNo]; this->minx0=this->maxx0=sline.m_line.pt[0].x; this->miny0=this->maxy0=sline.m_line.pt[0].y; for(n=0;n<sline.m_line.ptno;n++) this->m_line.pt[n].x=sline.m_line.pt[n].x; this->m_line.pt[n].y=sline.m_line.pt[n].y; this->minx0=this->minx0<sline.m_line.pt[n].x?this->minx0:sline.m_line.pt[n].x; this->maxx0=this->maxx0>sline.m_line.pt[n].x?this->maxx0:sline.m_line.pt[n].x; 12
this->miny0=this->miny0<sline.m_line.pt[n].y?this->miny0:sline.m_line.pt[n].y; this->maxy0=this->maxy0>sline.m_line.pt[n].y?this->maxy0:sline.m_line.pt[n].y; CPlines CPlines::operator=(CPlines &sline) if(&sline!=this) this->m_color=sline.m_color; this->m_npenwidth=sline.m_npenwidth; this->m_line.ptno=sline.m_line.ptno; this->m_line.bz=sline.m_line.bz; this->m_line.hzz=sline.m_line.hzz; this->m_line.pt=new Bpoint[sLine.m_line.PtNo]; int n; this->minx0=this->maxx0=sline.m_line.pt[0].x; this->miny0=this->maxy0=sline.m_line.pt[0].y; for(n=0;n<sline.m_line.ptno;n++) this->m_line.pt[n].x=sline.m_line.pt[n].x; this->m_line.pt[n].y=sline.m_line.pt[n].y; this->minx0=this->minx0<sline.m_line.pt[n].x?this->minx0:sline.m_line.pt[n].x; this->maxx0=this->maxx0>sline.m_line.pt[n].x?this->maxx0:sline.m_line.pt[n].x; this->miny0=this->miny0<sline.m_line.pt[n].y?this->miny0:sline.m_line.pt[n].y; this->maxy0=this->maxy0>sline.m_line.pt[n].y?this->maxy0:sline.m_line.pt[n].y; return *this; BOOL CPlines::Draw(CDC *pdc,double xmin,double xmax,double ymin,double ymax,double blc,colorref cr,int type) int i; CString cs; if(type==0) double xx,yy,dl; dl=(xmax-xmin)>(ymax-ymin)?(xmax-xmin):(ymax-ymin); blc=blc*4; xx=(m_line.pt[0].x-xmin)*blc+100; yy=(ymax-m_line.pt[0].y)*blc+100; pdc->moveto(int(xx),int(yy)); 13
for(i=1;i<m_line.ptno;i++) xx=(m_line.pt[i].x-xmin)*blc+100; yy=(ymax-m_line.pt[i].y)*blc+100; pdc->lineto(int(xx),int(yy)); CPoint pt[10000]; CBrush brush,*oldbrush; brush.createsolidbrush(cr); oldbrush=pdc->selectobject(&brush); double dl; dl=(xmax-xmin)>(ymax-ymin)?(xmax-xmin):(ymax-ymin); blc=blc*4; pt[0].x=int((m_line.pt[0].x-xmin)*blc+100); pt[0].y=int((ymax-m_line.pt[0].y)*blc+100); for(i=1;i<m_line.ptno;i++) pt[i].x=int((m_line.pt[i].x-xmin)*blc+100); pt[i].y=int((ymax-m_line.pt[i].y)*blc+100); pdc->polygon(pt,m_line.ptno); return TRUE; void CPlines::FinishShape() int i; minx0=maxx0=m_line.pt[0].x; miny0=maxy0=m_line.pt[0].y; for(i=1;i<m_line.ptno;i++) minx0=minx0<m_line.pt[i].x?minx0:m_line.pt[i].x; maxx0=maxx0>m_line.pt[i].x?maxx0:m_line.pt[i].x; miny0=miny0<m_line.pt[i].y?miny0:m_line.pt[i].y; maxy0=maxy0>m_line.pt[i].y?maxy0:m_line.pt[i].y; m_rectbounding=crect(int(minx0),int(miny0),int(maxx0),int(maxy0)); m_rectbounding.inflaterect(csize(m_npenwidth,(int)m_npenwidth)); return; void CPlines::OffsetPoint(CPoint &p) CRect rect(int(this->minx0),int(this->miny0),int(this->maxx0),int(this->maxy0)); 14
rect.offsetrect(p); this->minx0=double(rect.left); this->miny0=double(rect.bottom); this->maxx0=double(rect.right); this->maxy0=double(rect.top); return; void CPlines::Serialize(CArchive &ar) CShape::Serialize(ar); int i; if(ar.isstoring()) ar<<m_line.bz<<m_line.hzz<<m_line.ptno; for(i=0;i<m_line.ptno;i++) ar<<m_line.pt[i].x<<m_line.pt[i].y; ar>>m_line.bz>>m_line.hzz>>m_line.ptno; m_line.pt=new Bpoint[m_line.PtNo]; for(i=0;i<m_line.ptno;i++) ar>>m_line.pt[i].x>>m_line.pt[i].y; BOOL CPlines::IsPoint(double x, double y, double jl, double blc) int i; double xx,x1,x2,y1,y2; CString cs; if(this->m_bdelete) return FALSE; GetRect(&x1,&y1,&x2,&y2); if(!(x>=x1-jl&&x<=x2+jl&&y>=y1-jl&&y<=y2+jl)) return FALSE; for(i=0;i<m_line.ptno-1;i++) xx=pointline(x,y,m_line.pt[i].x,m_line.pt[i].y,m_line.pt[i+1].x,m_line.pt[i+1].y); if(xx<jl) return TRUE; return FALSE; void CPlines::GetRect(double *minx, double *miny, double *maxx, double *maxy) double x1,y1,x2,y2; x1=x2=m_line.pt[0].x; 15
y1=y2=m_line.pt[0].y; for(int i=0;i<m_line.ptno;i++) x1=x1<m_line.pt[i].x?x1:m_line.pt[i].x; y1=y1<m_line.pt[i].y?y1:m_line.pt[i].y; x2=x2>m_line.pt[i].x?x2:m_line.pt[i].x; y2=y2>m_line.pt[i].y?y2:m_line.pt[i].y; *minx=x1;*maxx=x2;*miny=y1;*maxy=y2; (3) 增加类 CGeoLayer 方法同前 类的类型同 CShape, 类的基类为 :CObject 类的定义如下 : // GeoLayer.h: interface for the CGeoLayer class. // ////////////////////////////////////////////////////////////////////// #if!defined(afx_geolayer_h 06537374_218C_11D8_A6BC_00A0CCCF0ED3 INCLUDED_) #define AFX_GEOLAYER_H 06537374_218C_11D8_A6BC_00A0CCCF0ED3 INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CGeoLayer : public CObject public: virtual BOOL LoadSave(FILE *fl,bool yn); virtual BOOL Draw(CDC *pdc,double xmin,double ymin,double xmax,double ymax,double blc); void SetLayerPenColor(COLORREF pencolor); void SetLayerBrushColor(COLORREF brushcolor,int brushtype); void SetLayerLineType(int linetype,int linewide); CGeoLayer(); CGeoLayer(CString LayerName,CString LayerType,CRect LayerRect); virtual ~CGeoLayer(); protected: CString m_layername;// 图层名 CString m_layertype;// 图层类型 CRect m_layerrect;// 图层最大区域 COLORREF m_colorpen;// 笔颜色 COLORREF m_colorbrush;// 充填刷颜色 int m_brushtype;// 画刷类型 ;0: 原色 ;1: 阴影 ;2: 图案 int m_linewide;// 线宽 int m_linetype;// 线型 ; #endif //!defined(afx_geolayer_h 06537374_218C_11D8_A6BC_00A0CCCF0ED3 INCLUDED_) // GeoLayer.cpp: implementation of the CGeoLayer class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "DrawProjection.h" 16
#include "GeoLayer.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]= FILE ; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CGeoLayer::CGeoLayer() m_layername="0"; m_layertype=" 等高线 "; m_layerrect=crect(0,0,500,500); m_colorpen=rgb(0,0,0); m_colorbrush=rgb(0,0,0); m_linewide=1; m_linetype=ps_solid; CGeoLayer::CGeoLayer(CString LayerName,CString LayerType,CRect LayerRect) m_layername=layername; m_layertype=layertype; m_layerrect=layerrect; CGeoLayer::~CGeoLayer() void CGeoLayer::SetLayerPenColor(COLORREF pencolor) m_colorpen=pencolor; void CGeoLayer::SetLayerBrushColor(COLORREF brushcolor,int brushtype) m_colorbrush=brushcolor; void CGeoLayer::SetLayerLineType(int linetype,int linewide) m_linewide=linewide; m_linetype=linetype; BOOL CGeoLayer::LoadSave(FILE *fl, BOOL yn) if(!yn) char ln[80],lt[80]; fscanf(fl,"%s%s",ln,lt); m_layername.format("%s",ln); m_layertype.format("%s",lt); 17
fscanf(fl,"%d%d%d%d",&m_layerrect.left,&m_layerrect.bottom, &m_layerrect.right,&m_layerrect.top); fscanf(fl,"%d%d%d",&m_colorpen,&m_colorbrush,&m_brushtype); fscanf(fl,"%d%d",&m_linetype,&m_linewide); fprintf(fl,"%s %s",m_layername,m_layertype); fprintf(fl," %d %d %d %d",m_layerrect.left,m_layerrect.bottom,m_layerrect.right,m_layerrect.top); fprintf(fl," %d %d %d",m_colorpen,m_colorbrush,m_brushtype); fprintf(fl," %d %d\n",m_linetype,m_linewide); return TRUE; BOOL CGeoLayer::Draw(CDC *pdc,double xmin,double ymin,double xmax,double ymax,double blc) return TRUE; (3) 增加类 CGeoLayerWithProjection 方法同前 类的类型同 CGeoLayer, 类的基类为 :CGeoLayer 类的定义如下 : // GeoLayerWithProjection.h: interface for the CGeoLayerWithProjection class. // ////////////////////////////////////////////////////////////////////// #if!defined(afx_geolayerwithprojection_h 06537375_218C_11D8_A6BC_00A0CCCF0ED3 INCLUDED_) #define AFX_GEOLAYERWITHPROJECTION_H 06537375_218C_11D8_A6BC_00A0CCCF0ED3 INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "Pline.h" #include "GeoLayer.h" #define MAXPOINTNUM 50000 class CGeoLayerWithProjection : public CGeoLayer public: int m_linenum; int m_ptnum; double m_xworldmin,m_yworldmin,m_xworldmax,m_yworldmax; CGeoLayerWithProjection(); virtual ~CGeoLayerWithProjection(); void SetProjectionType(int type,double scale); Bpoint CalProjection(int type,double l,double b); void SetMapExtent(double x1,double y1,double x2,double y2); void Resize(int ll,int tt,int ww,int hh); void AdjustScale(); void XYWorldToScreen(double x,double y,int xx[],int yy[]); void XYScreenToWorld(int x,int y,double xx[],double yy[]); void ZoomIn(); 18
void ZoomOut(); void ZoomInAt(int x,int y); void ZoomOutAt(int x,int y); void Pan(int x1,int y1,int x2,int y2); void ZoomWindow(int x1,int y1,int x2,int y2); virtual BOOL LoadSave(FILE *fl,bool yn); virtual BOOL Draw(CDC *pdc,double xmin,double ymin,double xmax,double ymax,double blc); protected: int m_projectiontype; double m_l,m_b; Bpoint m_pt[maxpointnum],m_pt0; double m_scale; int m_screenleft,m_screenright,m_screenbottom,m_screentop; ; #endif //!defined(afx_geolayerwithprojection_h 06537375_218C_11D8_A6BC_00A0CCCF0ED3 INCLUDED_) // GeoLayerWithProjection.cpp: implementation of the CGeoLayerWithProjection class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "DrawProjection.h" #include "GeoLayerWithProjection.h" #include "math.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]= FILE ; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CGeoLayerWithProjection::CGeoLayerWithProjection() // 初始化世界坐标和窗口坐标范围 // 世界坐标的极值为 X 轴 ( 经度 ) -180 至 +180,Y 轴 ( 纬度 ) -90 至 +90 // 窗口坐标总是从 (0, 0) 开始, 可绘图区域程序初始时暂定为 (640, 480) m_projectiontype=0; m_scale=1.0; m_xworldmin = -180; m_yworldmin = -90; m_xworldmax = 180; m_yworldmax = 90; m_screenleft = 0; m_screentop = 0; m_screenright = 1024; m_screenbottom = 768; 19
CGeoLayerWithProjection::~CGeoLayerWithProjection() void CGeoLayerWithProjection::SetProjectionType(int type,double scale) m_projectiontype=type; m_scale=scale; Bpoint CGeoLayerWithProjection::CalProjection(int type,double l,double b) Bpoint pt; pt.x=0.0; pt.y=0.0; static double Pi=3.1415926535897; static double er=6378245.0; l=l*pi/180.0;// 经度 b=b*pi/180.0;// 纬度 double x,y; if(type==1)// 正轴等角方位投影 ( 球面投影 ) x=(pi/2.0-b)/2.0; if(x==pi/2.0) x=x-0.0872664625997164788461845384244306; if(x==-pi/2.0) x=x+0.0872664625997164788461845384244306; pt.x=2.0*er*cos(l)*tan(x)/m_scale; pt.y=2.0*er*sin(l)*tan(x)/m_scale; if(type==2)// 正轴等积方位投影 ( 兰勃特投影 ) pt.x=2.0*er*cos(l)*sin((pi/2.0-b)/2.0)/m_scale; pt.y=2.0*er*sin(l)*sin((pi/2.0-b)/2.0)/m_scale; if(type==3)// 正轴等距方位投影 ( 波斯托投影 ) pt.x=er*cos(l)*((pi/2.0-b)/2.0)/m_scale; pt.y=er*sin(l)*((pi/2.0-b)/2.0)/m_scale; if(type==4)// 等角正轴切圆柱投影 ( 墨卡托投影 ) x=pi/4.0+b/2.0; if(x==pi/2.0) x=x-0.0000001; if(x==-pi/2.0) x=x+0.0000001; if(fabs(tan(x))<0.000001) y=0.00001; y=fabs(tan(x)); pt.x=er*l/m_scale; 20
pt.y=er*log(y)/m_scale; if(type==5)// 高斯 - 克吕格投影 double s,n,ita; if(b==pi/2.0) b=b-0.00001; if(b==-pi/2.0) b=b+0.00001; s=6367558.0*b+(-16000.0*sin(2.0*b)+20.0*sin(4.0*b)-0.022*sin(6.0*b) +0.000031*sin(8.0*b)); n=6367558.0/sqrt(1.0-0.00669*sin(b)*sin(b)); ita=0.00674*cos(b)*cos(b); pt.x=l*n*cos(b)+n*l*l*l*cos(b)*cos(b)*cos(b)*(1.0-tan(b)*tan(b) +ita)/6.0+n*l*l*l*l*l*cos(b)*cos(b)*cos(b)*cos(b)*cos(b)*(5.0-18*tan(b) *tan(b)+tan(b)*tan(b)*tan(b)*tan(b)+14.0*ita-58.0*ita*tan(b)*tan(b))/120.0; pt.y=s+n*l*l*sin(b)*cos(b)/2.0+n*l*l*l*l*sin(b)*cos(b)*cos(b)*cos(b)*(5.0 -tan(b)*tan(b)+9.0*ita+4.0*ita*ita)/24.0+n*l*l*l*l*l*l*sin(b)*cos(b) *cos(b)*cos(b)*cos(b)*cos(b)*(61.0-58.0*tan(b)*tan(b)+tan(b)*tan(b) *tan(b)*tan(b)+270.0*ita*ita-330.0*ita*tan(b)*tan(b))/720.0; pt.x=pt.x/m_scale; pt.y=pt.y/m_scale; if(type==6)// 桑生投影 pt.x=er*l*cos(b)/m_scale; pt.y=er*b/m_scale; if(type==7)// 摩尔威特投影 pt.x=2.0*sqrt(2.0)*er*l*cos(b)/m_scale; pt.y=sqrt(2.0)*er*sin(b)/m_scale; if(type==8)// 爱凯特正弦伪圆柱投影 pt.x=2.0*er*l*cos(b/2.0)*cos(b/2.0)/sqrt(2.0+pi)/m_scale; pt.y=2.0*er*b/sqrt(2.0+pi)/m_scale; if(type==9)// 爱凯特椭圆伪圆柱投影 pt.x=2.0*er*l*(cos(b)+1.0)/sqrt(pi*(4.0+pi))/m_scale; pt.y=2.0*er*sin(b)/sqrt(pi/(4.0+pi))/m_scale; if(type==10)// 等面积伪圆锥投影 ( 彭纳投影 ) double s,n,pp,rr,s1,n1,b1; b1=pi/6.0; s=6367558.0*b-16000.0*sin(2.0*b)+20.0*sin(4.0*b)-0.022*sin(6.0*b) +0.000031*sin(8.0*b); n=6367558.0/sqrt(1.0-0.00669*sin(b)*sin(b)); s1=6367558.0*b1-16000.0*sin(2.0*b1)+20.0*sin(4.0*b1)-0.022*sin(6.0*b1) +0.000031*sin(8.0*b1); n1=6367558.0/sqrt(1.0-0.00669*sin(b1)*sin(b1)); 21
pp=n/tan(b1)+s1-s; rr=n*cos(b); pt.x=pp*sin(l*rr/pp)/m_scale; pt.y=-pp*cos(l*rr/pp)/m_scale; if(type==11)// 普通多圆锥投影 ( 美国多圆锥投影 ) double s,n; b=b+0.001*pi/180.0; s=6367558.0*b-16000.0*sin(2.0*b)+20.0*sin(4.0*b)-0.022*sin(6.0*b) +0.000031*sin(8.0*b); n=6367558.0/sqrt(1.0-0.00669*sin(b)*sin(b)); pt.x=n/tan(b)*sin(l*sin(b))/m_scale; pt.y=(s+n/tan(b)*(1-cos(l*sin(b))))/m_scale; m_pt0=pt; return pt; BOOL CGeoLayerWithProjection::LoadSave(FILE *fl,bool yn) return TRUE; BOOL CGeoLayerWithProjection::Draw(CDC *pdc,double xmin,double ymin,double xmax,double ymax,double blc) return TRUE; void CGeoLayerWithProjection::SetMapExtent(double x1,double y1,double x2,double y2)// 设置世界坐标范围 m_xworldmin = x1; m_yworldmin = y1; m_xworldmax = x2; m_yworldmax = y2; AdjustScale(); void CGeoLayerWithProjection::Resize(int ll,int tt,int ww,int hh)// 绘图区域坐标调整为新的宽度和高度 m_screenleft = ll; m_screentop = tt; m_screenright = ww + ll; m_screenbottom = hh + tt; AdjustScale(); void CGeoLayerWithProjection::AdjustScale()// 调整转换比例参数 22
// 计算坐标转换比例参数 double sx= (m_xworldmax - m_xworldmin) / (m_screenright - m_screenleft); double sy= (m_yworldmax - m_yworldmin) / (m_screenbottom- m_screentop); // 取比较大的一个参数以保证显示出尽可能多的图形 // X 轴和 Y 轴使用系统的参数, 以保证图形不变形 if (sx < sy ) m_scale = 1.0/sy; m_scale = 1.0/sx; // 同时更新世界坐标范围 m_xworldmax = m_xworldmin + (m_screenright - m_screenleft) / m_scale; m_yworldmin= m_yworldmax - (m_screenbottom- m_screentop) / m_scale; void CGeoLayerWithProjection::XYWorldToScreen(double x,double y,int xx[],int yy[])// 世界坐标转换为屏幕坐标 xx[0] = int ((x - m_xworldmin) *m_scale) + m_screenleft; yy[0] = int ((m_yworldmax - y) *m_scale) + m_screentop; void CGeoLayerWithProjection::XYScreenToWorld(int x,int y,double xx[],double yy[])// 屏幕坐标转换为世界坐标 xx[0]= (x - m_screenleft) / m_scale + m_xworldmin; yy[0]= m_yworldmax - (y-m_screentop) / m_scale; void CGeoLayerWithProjection::ZoomIn()// 放大 double xx = (m_xworldmax - m_xworldmin) / 4.0; double yy = (m_yworldmax - m_yworldmin) / 4.0; SetMapExtent(m_xWorldMin + xx, m_yworldmin + yy, m_xworldmax - xx, m_yworldmax - yy); void CGeoLayerWithProjection::ZoomOut()// 缩小 double xx = (m_xworldmax - m_xworldmin) / 4.0; double yy = (m_yworldmax - m_yworldmin) / 4.0; SetMapExtent(m_xWorldMin - xx, m_yworldmin - yy, m_xworldmax + xx, m_yworldmax + yy); void CGeoLayerWithProjection::ZoomInAt(int x,int y)// 在某点放大 int x1[1], y1[1], x2, y2; double x0[1], y0[1]; XYScreenToWorld(x, y, x0, y0); ZoomIn(); XYWorldToScreen(x0[0], y0[0], x1, y1); x2 = (m_screenright - m_screenleft) / 2; 23
y2 = (m_screenbottom- m_screentop) / 2; Pan(x1[0], y1[0], x2, y2); void CGeoLayerWithProjection::ZoomOutAt(int x,int y)// 在某点缩小 int x1[1], y1[1], x2, y2; double x0[1], y0[1]; XYScreenToWorld(x, y, x0, y0); ZoomOut(); XYWorldToScreen(x0[0], y0[0], x1, y1); x2 = (m_screenright - m_screenleft) / 2; y2 = (m_screenbottom- m_screentop) / 2; Pan(x1[0], y1[0], x2, y2); void CGeoLayerWithProjection::Pan(int x1,int y1,int x2,int y2)// 平移 double xx1[1], yy1[1], xx2[1], yy2[1], xx, yy; XYScreenToWorld(x1, y1, xx1, yy1); XYScreenToWorld(x2, y2, xx2, yy2); xx = xx2[0] - xx1[0]; yy = yy2[0] - yy1[0]; SetMapExtent(m_xWorldMin - xx, m_yworldmin - yy, m_xworldmax - xx, m_yworldmax - yy); void CGeoLayerWithProjection::ZoomWindow(int x1,int y1,int x2,int y2) double x, y, xx1[1], yy1[1], xx2[1], yy2[1]; if (x1 == x2 y1 == y2) ZoomInAt((x1+x2) / 2, (y1+y2) / 2); exit(0); XYScreenToWorld(x1, y1, xx1, yy1); XYScreenToWorld(x2, y2, xx2, yy2); if (xx1[0] > xx2[0]) x = xx1[0]; xx1[0]= xx2[0]; xx2[0]= x; if( yy1[0] > yy2[0]) y = yy1[0]; yy1[0]= yy2[0]; yy2[0]= y; SetMapExtent(xx1[0], yy1[0], xx2[0], yy2[0]); 3. 增加菜单项 24
(1) 点击资源视图, 出现如图 10 情形, 点 DrawProjection resource 前面 + 号展 图 10 增加菜单项界面开各资源项如图, 然后点击 Menu 前的 + 号出现主菜单资源的标志 :IDR_MAINFRAME, 双击标志后, 出现右面的菜单条, 将最后虚框拖至 查看 项之后 (2) 将鼠标移动到虚框上点右键出现图 11 菜单项, 选择 Properties 项, 后出现如图 12 的属性对话框 图 11 图 12 (3) 点击图 12 左上角的 Keep Visible 按钮, 保持属性对话框停留在屏幕上 (4) 如果是最上层菜单项, 则只在 Caption 项里填入相应内容, 其它项需在 ID 项中写入 ID, 一般 ID 均用大写英文字母, 并可用 _ 线相隔 本实验中增加的菜单项内容为 :( 参见图 10) 25
菜单 菜单项 (Caption) 命令 ID 导入数据 导入区域数据 ID_INPUT_REGION 导入线型数据 ID_INPUT_LINE 投影类型 没有投影 ID_NO_PROJECTION 球面投影 ID_SPHERE_PROJECTION 兰勃特投影 ID_LANBT_PROJECTION 波斯托投影 ID_BST_PROJECTION 墨卡托投影 ID_MKT_PROJECTION 高斯 - 克吕格投影 ID_GAUSS_PROJECTION 桑生投影 ID_SANSON_PROJECTION 摩尔威特投影 ID_MEW_PROJECTION 爱凯特正弦伪圆柱投影 ID_ECKERT_SIN 爱凯特椭圆伪圆柱投影 ID_ECKERT_TY 彭纳投影 ID_PENA_PROJECTION 美国多圆锥投影 ID_AMERICAN_PROJECTION 4. 加入命令消息控制函数 (1) 在输入完各菜单项后, 将鼠标移动到菜单条上点右键出现图 11 的菜单, 选择 ClassWizard 项后出现图 13 的标签式对话框, 在 Message Maps 项中的 Class name 项中选 图 13 26
择 CDrawProjectionView 后, 在 Object IDs 中找到上述所建立的菜单项 ID, 如 ID_ECKERT_SIN, 点击后会在 Messages 出现 COMMAND 项, 双击其并选择默认值, 即建立了命令消息控制函数 (2) 用同样的方法建立其它命令消息控制函数 5. 增加对话框资源 (1) 点击资源视图并展开各资源项 ( 方法同前 ) (2) 点击 Dialog 项, 并点右键出现弹出式菜单项如图 14, 选择 Insert Dialog 项后会在对话框资源中增加一项, 双击后出现对话框编辑界面如图 15 图 14 图 15 (3) 设计的对话框如图 15 其中对话框的 ID 为 :IDD_SELECT_COOR, 其它见图 16 17 18 19 27
图 16 图 17 28
图 18 图 19 (4) 设计好对话框后, 点右键出现如图 11 的弹出式菜单, 选择 ClassWizard 项后出现建立新类的对话框, 在类名中填入 :CSelectCoor0, 其它选择默认值 29
(5) 然后选择如图 13 中的 Member Variables 项, 加入控件变量如图 20 (6) 点 OK 确认 图 20 6. 在 DrawProjectionDoc 的头文件中增加如下阴影内容 ( 注意位置 ): #include "Pline.h" class CDrawProjectionDoc : public CDocument protected: // create from serialization only CDrawProjectionDoc(); DECLARE_DYNCREATE(CDrawProjectionDoc) // Attributes public: CTypedPtrArray<CObArray,CPlines*>m_PLineArray; 的对象.. 7. 在 DrawProjectionDoc 类中增加虚函数 // 管理连续直线对象指针 30
方法见图 21, 选中 DrawProjectionDoc 类点右键出现弹出式菜单后, 选择 Add Virtual Function 项, 出现对话框后, 双击 DeleteContents 和 Serialize 图 21 在虚函数中增加内容 : // DrawProjectionDoc.cpp : implementation of the CDrawProjectionDoc class // void CDrawProjectionDoc::Serialize(CArchive& ar) if (ar.isstoring()) // TODO: add storing code here // TODO: add loading code here m_plinearray.serialize(ar); 31
void CDrawProjectionDoc::DeleteContents() long nn; nn=this->m_plinearray.getupperbound()+1; while(nn--) delete m_plinearray.getat(nn); m_plinearray.removeat(nn); this->updateallviews(null); this->setmodifiedflag(true); CDocument::DeleteContents(); CDocument::DeleteContents(); 8. 在 DrawProjectionView 类中增加变量和函数增加后的内容如下 : // DrawProjectionView.h : interface of the CDrawProjectionView class // ///////////////////////////////////////////////////////////////////////////// #if!defined(afx_drawprojectionview_h 0653736C_218C_11D8_A6BC_00A0CCCF0ED3 INCLUDED_) #define AFX_DRAWPROJECTIONVIEW_H 0653736C_218C_11D8_A6BC_00A0CCCF0ED3 INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "GeoLayerWithProjection.h" class CDrawProjectionView : public CView protected: // create from serialization only CDrawProjectionView(); DECLARE_DYNCREATE(CDrawProjectionView) // Attributes public: CDrawProjectionDoc* GetDocument(); 32
// Operations public: // Overrides // ClassWizard generated virtual function overrides //AFX_VIRTUAL(CDrawProjectionView) public: virtual void OnDraw(CDC* pdc); // overridden to draw this view virtual BOOL PreCreateWindow(CREATESTRUCT& cs); protected: //AFX_VIRTUAL // Implementation public: void DrawGrid(CDC *pdc,int type); virtual ~CDrawProjectionView(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif protected: BOOL bshowprojection; int m_type; Spline m_line[3000]; Spline m_line0[3000]; Spline slines; BOOL bcoor; int LineNumber; double m_blc; double MaxX,MinX,MaxY,MinY,MaxH,MinH; // Generated message map functions protected: //AFX_MSG(CDrawProjectionView) afx_msg void OnNoProjection(); 33
; afx_msg void OnSphereProjection(); afx_msg void OnLanbtProjection(); afx_msg void OnAmericanProjection(); afx_msg void OnBstProjection(); afx_msg void OnEckertSin(); afx_msg void OnEckertTy(); afx_msg void OnGaussProjection(); afx_msg void OnMewProjection(); afx_msg void OnMktProjection(); afx_msg void OnPenaProjection(); afx_msg void OnSansonProjection(); afx_msg void OnInputRegion(); afx_msg void OnInputLine(); //AFX_MSG DECLARE_MESSAGE_MAP() #ifndef _DEBUG // debug version in DrawProjectionView.cpp inline CDrawProjectionDoc* CDrawProjectionView::GetDocument() return (CDrawProjectionDoc*)m_pDocument; #endif ///////////////////////////////////////////////////////////////////////////// //AFX_INSERT_LOCATION // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif //!defined(afx_drawprojectionview_h 0653736C_218C_11D8_A6BC_00A0CCCF0ED3 I NCLUDED_) 增加后的 DrawProjectionView.cpp 文件为 : // DrawProjectionView.cpp : implementation of the CDrawProjectionView class // #include "stdafx.h" #include "DrawProjection.h" #include "DrawProjectionDoc.h" #include "DrawProjectionView.h" #include "SelectCoor0.h" 34
#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = FILE ; #endif ///////////////////////////////////////////////////////////////////////////// // CDrawProjectionView IMPLEMENT_DYNCREATE(CDrawProjectionView, CView) BEGIN_MESSAGE_MAP(CDrawProjectionView, CView) //AFX_MSG_MAP(CDrawProjectionView) ON_COMMAND(ID_NO_PROJECTION, OnNoProjection) ON_COMMAND(ID_SPHERE_PROJECTION, OnSphereProjection) ON_COMMAND(ID_LANBT_PROJECTION, OnLanbtProjection) ON_COMMAND(ID_AMERICAN_PROJECTION, OnAmericanProjection) ON_COMMAND(ID_BST_PROJECTION, OnBstProjection) ON_COMMAND(ID_ECKERT_SIN, OnEckertSin) ON_COMMAND(ID_ECKERT_TY, OnEckertTy) ON_COMMAND(ID_GAUSS_PROJECTION, OnGaussProjection) ON_COMMAND(ID_MEW_PROJECTION, OnMewProjection) ON_COMMAND(ID_MKT_PROJECTION, OnMktProjection) ON_COMMAND(ID_PENA_PROJECTION, OnPenaProjection) ON_COMMAND(ID_SANSON_PROJECTION, OnSansonProjection) ON_COMMAND(ID_INPUT_REGION, OnInputRegion) ON_COMMAND(ID_INPUT_LINE, OnInputLine) //AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDrawProjectionView construction/destruction CDrawProjectionView::CDrawProjectionView() // TODO: add construction code here bshowprojection=false; m_type=0; CDrawProjectionView::~CDrawProjectionView() BOOL CDrawProjectionView::PreCreateWindow(CREATESTRUCT& cs) // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs 35
return CView::PreCreateWindow(cs); ///////////////////////////////////////////////////////////////////////////// // CDrawProjectionView drawing void CDrawProjectionView::OnDraw(CDC* pdc) CDrawProjectionDoc* pdoc = GetDocument(); ASSERT_VALID(pDoc); COLORREF cr; for(int i=0;i<this->getdocument()->m_plinearray.getsize();i++) cr=rgb((i%128+127),(i%192+63),i%255); this->getdocument()->m_plinearray.getat(i)->draw(pdc,minx,maxx,miny,maxy,m_blc,cr,1); if(bshowprojection) DrawGrid(pDC,m_Type); ///////////////////////////////////////////////////////////////////////////// // CDrawProjectionView printing BOOL CDrawProjectionView::OnPreparePrinting(CPrintInfo* pinfo) // default preparation return DoPreparePrinting(pInfo); void CDrawProjectionView::OnBeginPrinting(CDC* /*pdc*/, CPrintInfo* /*pinfo*/) // TODO: add extra initialization before printing void CDrawProjectionView::OnEndPrinting(CDC* /*pdc*/, CPrintInfo* /*pinfo*/) // TODO: add cleanup after printing ///////////////////////////////////////////////////////////////////////////// // CDrawProjectionView diagnostics #ifdef _DEBUG void CDrawProjectionView::AssertValid() const CView::AssertValid(); void CDrawProjectionView::Dump(CDumpContext& dc) const CView::Dump(dc); 36
CDrawProjectionDoc* CDrawProjectionView::GetDocument() // non-debug version is inline ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDrawProjectionDoc))); return (CDrawProjectionDoc*)m_pDocument; #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CDrawProjectionView message handlers void CDrawProjectionView::DrawGrid(CDC *pdc,int type) CGeoLayerWithProjection Map1; if(type==7) Map1.Resize(100,200,400,600); Map1.Resize(100,20,800,600); int ii,jj,linenum; double lo,la,x,y,x1,y1; Bpoint ptt; int xx[1],yy[1]; CPoint pt0[5000]; CPen pen,pen1,pen2,*oldpen; pen1.createpen(ps_solid,1,rgb(128,128,128)); pen2.createpen(ps_solid,1,rgb(255,0,0)); oldpen=pdc->selectobject(&pen1); CBrush brush; double xmin,ymin,xmax,ymax; xmin=ymin=1.0e34; xmax=ymax=-1.0e34; if(!binputline) AfxMessageBox(" 请输入线型数据!"); OnInputLine(); for(ii=0;ii<linenumber;ii++) LineNum=this->GetDocument()->m_PLineArray.GetAt(ii)->m_line.PtNo; m_line0[ii].bz=this->getdocument()->m_plinearray.getat(ii)->m_line.bz; m_line0[ii].ptno=linenum; m_line0[ii].pt=new Bpoint[LineNum]; for(jj=0;jj<linenum;jj++) x=this->getdocument()->m_plinearray.getat(ii)->m_line.pt[jj].x; y=this->getdocument()->m_plinearray.getat(ii)->m_line.pt[jj].y; if(type>0) ptt=map1.calprojection(type,x,y); x1=ptt.x; y1=ptt.y; x1=x; 37
38 y1=y; m_line0[ii].pt[jj].x=x1; m_line0[ii].pt[jj].y=y1; xmin=min(xmin,x1); xmax=max(xmax,x1); ymin=min(ymin,y1); ymax=max(ymax,y1); if(type==1) Map1.SetMapExtent(xmin/4.5,ymin/4.5,xmax/4.5,ymax/4.5); if(type==4) Map1.SetMapExtent(xmin,ymin/6.0,xmax,ymax/5.0); if(type==5) Map1.SetMapExtent(xmin,ymin/4.0,xmax,ymax/4.0); Map1.SetMapExtent(xmin,ymin,xmax,ymax); for(ii=0;ii<linenumber;ii++) brush.createsolidbrush(rgb(ii%128+127,ii%192+63,ii%255)); pdc->selectobject(&brush); if(ii==linenumber-10 ii==linenumber-38) pdc->selectobject(&pen2); pdc->selectobject(&pen1); for(jj=0;jj<m_line0[ii].ptno;jj++) x=m_line0[ii].pt[jj].x; y=m_line0[ii].pt[jj].y; Map1.XYWorldToScreen(x,y,xx,yy); if(m_line0[ii].bz==1) if(jj==0) pdc->moveto(xx[0],yy[0]); pdc->lineto(xx[0],yy[0]); pt0[jj].x=xx[0]; pt0[jj].y=yy[0]; if(m_line0[ii].bz==2) pdc->polygon(pt0,m_line0[ii].ptno); brush.deleteobject(); pen1.deleteobject(); pen2.deleteobject(); pdc->selectobject(oldpen);
void CDrawProjectionView::OnNoProjection() m_type=0; bshowprojection=true; Invalidate(); void CDrawProjectionView::OnSphereProjection() m_type=1; bshowprojection=true; Invalidate(); void CDrawProjectionView::OnLanbtProjection() m_type=2; bshowprojection=true; Invalidate(); void CDrawProjectionView::OnBstProjection() m_type=3; bshowprojection=true; Invalidate(); void CDrawProjectionView::OnMktProjection() m_type=4; bshowprojection=true; Invalidate(); void CDrawProjectionView::OnGaussProjection() m_type=5; bshowprojection=true; Invalidate(); void CDrawProjectionView::OnSansonProjection() m_type=6; bshowprojection=true; Invalidate(); void CDrawProjectionView::OnMewProjection() m_type=7; bshowprojection=true; Invalidate(); 39
void CDrawProjectionView::OnEckertSin() m_type=8; bshowprojection=true; Invalidate(); void CDrawProjectionView::OnEckertTy() m_type=9; bshowprojection=true; Invalidate(); void CDrawProjectionView::OnPenaProjection() m_type=10; bshowprojection=true; Invalidate(); void CDrawProjectionView::OnAmericanProjection() m_type=11; bshowprojection=true; Invalidate(); void CDrawProjectionView::OnInputRegion() int plnn=this->getdocument()->m_plinearray.getsize(); if(plnn>0) this->getdocument()->m_plinearray.removeall(); CClientDC dc(this); this->onpreparedc(&dc); CFileDialog *d_popenfile=new CFileDialog(TRUE); if(!d_popenfile) return ; d_popenfile->m_ofn.lpstrfilter=_t("data Files(*.dat)\0*.dat\0" "Text Files(*.txt)\0*.txt\0" "All Files(*.*)\0*.*\0"); int iret=d_popenfile->domodal(); if(iret!=idok) return ; CString csfile=d_popenfile->getpathname(); if(csfile.getlength()<1) return ; FILE *fp1; if((fp1=fopen(csfile,"r"))==null) AfxMessageBox(_T("Can not Open File")); return ; 40
CString bl1,bl2; CSelectCoor0 cdlg; cdlg.m_coor=0; cdlg.m_blc="1:1"; if(cdlg.domodal()==idok) if(cdlg.m_coor==0) bcoor=false; bcoor=true; int finds=cdlg.m_blc.find(':'); if(finds>0) bl1=cdlg.m_blc.left(cdlg.m_blc.find(':')); bl2=cdlg.m_blc.right(cdlg.m_blc.getlength()-cdlg.m_blc.find(':')-1); bl1=cdlg.m_blc; bl2="1"; if(cdlg.m_coor==0) m_blc=atof(bl1)/atof(bl2); m_blc=1000.0*atof(bl1)/atof(bl2); double lsdataz,lsdatax,lsdatay; int ids,rds; long i=0; MaxX=MaxY=MaxH=-1.0e10; MinX=MinY=MinH=1.0e10; while(!feof(fp1)) rds=fscanf(fp1,"%d%lf",&ids,&lsdataz); if(rds>0) slines.ptno=ids; slines.hzz=lsdataz; slines.pt=new Bpoint[sLines.PtNo+1]; MaxH>lsdataz?MaxH:lsdataz; MinH<lsdataz?MinH:lsdataz; for(int jj=0;jj<slines.ptno;jj++) fscanf(fp1,"%lf,%lf",&lsdatax,&lsdatay); if(bcoor) slines.pt[jj].x=lsdatay; slines.pt[jj].y=lsdatax; slines.pt[jj].x=lsdatax; slines.pt[jj].y=lsdatay; MaxX=MaxX>lsdatax?MaxX:lsdatax; MinX=MinX<lsdatax?MinX:lsdatax; 41
MaxY=MaxY>lsdatay?MaxY:lsdatay; MinY=MinY<lsdatay?MinY:lsdatay; if(slines.pt[0].x==slines.pt[slines.ptno-1].x&&slines.pt[0].y==slines.pt[slines.ptno-1 ].y) slines.bz=2;// 闭曲线 slines.pt[slines.ptno].x=slines.pt[0].x; slines.pt[slines.ptno].y=slines.pt[0].y; slines.ptno=slines.ptno+1; slines.bz=2;// 开曲线 CPlines *lines=new CPlines(sLines,1,RGB(0,0,0)); lines->finishshape(); lines->m_bdelete=false; lines->setdrawsort(1); lines->m_sort=1; this->getdocument()->m_plinearray.add(lines); i++; LineNumber=i; fclose(fp1); CPen blackpen; blackpen.createpen(ps_solid, 1, RGB(0, 0, 0)); COLORREF cr; for(i=0;i<this->getdocument()->m_plinearray.getsize();i++) cr=rgb((i%128+127),(i%192+63),i%255); this->getdocument()->m_plinearray.getat(i)->draw(&dc,minx,maxx,miny,maxy,m_blc,cr,1); return ; void CDrawProjectionView::OnInputLine() CClientDC dc(this); this->onpreparedc(&dc); CFileDialog *d_popenfile=new CFileDialog(TRUE); if(!d_popenfile) return ; d_popenfile->m_ofn.lpstrfilter=_t("data Files(*.dat)\0*.dat\0" "Text Files(*.txt)\0*.txt\0" "All Files(*.*)\0*.*\0"); int iret=d_popenfile->domodal(); if(iret!=idok) return ; CString csfile=d_popenfile->getpathname(); if(csfile.getlength()<1) return ; FILE *fp1; if((fp1=fopen(csfile,"r"))==null) 42
AfxMessageBox(_T("Can not Open File")); return ; CString bl1,bl2; CSelectCoor0 cdlg; cdlg.m_coor=0; cdlg.m_blc="1:1"; if(cdlg.domodal()==idok) if(cdlg.m_coor==0) bcoor=false; bcoor=true; int finds=cdlg.m_blc.find(':'); if(finds>0) bl1=cdlg.m_blc.left(cdlg.m_blc.find(':')); bl2=cdlg.m_blc.right(cdlg.m_blc.getlength()-cdlg.m_blc.find(':')-1); bl1=cdlg.m_blc; bl2="1"; if(cdlg.m_coor==0) m_blc=atof(bl1)/atof(bl2); m_blc=1000.0*atof(bl1)/atof(bl2); double lsdataz,lsdatax,lsdatay; int ids,rds,id; long i=0; MaxX=MaxY=MaxH=-1.0e50; MinX=MinY=MinH=1.0e50; while(!feof(fp1)) rds=fscanf(fp1,"%d,%d",&id,&ids); if(rds>0) slines.ptno=ids; slines.hzz=0.0; slines.pt=new Bpoint[sLines.PtNo]; for(int jj=0;jj<slines.ptno;jj++) fscanf(fp1,"%lf,%lf",&lsdatax,&lsdatay); if(bcoor) slines.pt[jj].x=lsdatay; slines.pt[jj].y=lsdatax; slines.pt[jj].x=lsdatax; slines.pt[jj].y=lsdatay; MaxX=MaxX>lsdatax?MaxX:lsdatax; 43
MinX=MinX<lsdatax?MinX:lsdatax; MaxY=MaxY>lsdatay?MaxY:lsdatay; MinY=MinY<lsdatay?MinY:lsdatay; if(slines.pt[0].x==slines.pt[slines.ptno-1].x&&slines.pt[0].y==slines.pt[slines.ptno-1 ].y) slines.bz=2;// 闭曲线 slines.bz=1;// 开曲线 CPlines *lines=new CPlines(sLines,1,RGB(0,0,0)); lines->finishshape(); lines->m_bdelete=false; lines->setdrawsort(1); lines->m_sort=1; this->getdocument()->m_plinearray.add(lines); i++; LineNumber=i; fclose(fp1); double lo,la; int ii,jj; lo=-180.0; for(jj=0;jj<37;jj++) slines.ptno=19; slines.pt=new Bpoint[19]; slines.hzz=0.0; la=-90.0; for(ii=0;ii<19;ii++) slines.pt[ii].x=lo; slines.pt[ii].y=la; la=la+10.0; lo=lo+10.0; if(slines.pt[0].x==slines.pt[slines.ptno-1].x&&slines.pt[0].y==slines.pt[slines.ptno-1 ].y) slines.bz=2;// 闭曲线 slines.bz=1;// 开曲线 CPlines *lines=new CPlines(sLines,1,RGB(0,0,0)); lines->finishshape(); lines->m_bdelete=false; lines->setdrawsort(1); lines->m_sort=1; this->getdocument()->m_plinearray.add(lines); 44
la=-90.0; for(ii=37;ii<56;ii++) slines.ptno=37; slines.pt=new Bpoint[37]; slines.hzz=0.0; lo=-180.0; for(jj=0;jj<37;jj++) slines.pt[jj].x=lo; slines.pt[jj].y=la; lo=lo+10.0; la=la+10.0; if(slines.pt[0].x==slines.pt[slines.ptno-1].x&&slines.pt[0].y==slines.pt[slines.ptno-1 ].y) slines.bz=2;// 闭曲线 slines.bz=1;// 开曲线 CPlines *lines=new CPlines(sLines,1,RGB(0,0,0)); lines->finishshape(); lines->m_bdelete=false; lines->setdrawsort(1); lines->m_sort=1; this->getdocument()->m_plinearray.add(lines); LineNumber=LineNumber+56; binputline=true; AfxMessageBox(" 输入数据完毕!"); return ; 9. 在 stdafx.h 文件中增加如下头文件 : #include <afxtempl.h> 10. 编译运行 45