⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drawshapeview.cpp

📁 用于地理信息系统(GIS)行业程序。 完整的鼠标交互式地图点、线、面的绘制
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// DrawShapeView.cpp : implementation of the CDrawShapeView class
//

#include "stdafx.h"
#include "DrawShape.h"

#include "DrawShapeDoc.h"
#include "DrawShapeView.h"
#include "Draw.h"
#include "ReadShapefile.h"
/*
#include "Direct.h" 加入该头文件以调用_getcwd
					该函数获得当前工作路径		
*/

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


CDrawShapeView* gpCDrawShapeView;
extern CGraphPara* gpCGraphPara;
int gHScreen,gWScreen;	//当前视图的高度和宽度

float xMinScreen,yMinScreen,xMaxScreen,yMaxScreen;

//全局函数,判断一矩形与当前视图屏幕是否相交
BOOL IsRectCross(float minX, float minY, float maxX, float maxY)
{
	if(minX > xMaxScreen || maxX < xMinScreen || 
		minY > yMaxScreen || maxY < yMinScreen)
	{
		return FALSE;
	}
	else
	{
		return TRUE;
	}
}

/////////////////////////////////////////////////////////////////////////////
// CDrawShapeView





IMPLEMENT_DYNCREATE(CDrawShapeView, CView)

BEGIN_MESSAGE_MAP(CDrawShapeView, CView)
//{{AFX_MSG_MAP(CDrawShapeView)
ON_UPDATE_COMMAND_UI(ID_INDICATOR_X,OnUpdateIndicatorX)
ON_UPDATE_COMMAND_UI(ID_INDICATOR_Y,OnUpdateIndicatorY)
ON_WM_SIZE()
ON_COMMAND(ID_TEST_DRAW, OnTestDraw)
ON_COMMAND(ID_DRAW_LINE, OnDrawLine)
ON_WM_LBUTTONDOWN()
ON_COMMAND(ID_DRAW_POLYLINE, OnDrawPolyline)
ON_COMMAND(ID_DRAW_POLYGON, OnDrawPolygon)
ON_WM_MOUSEMOVE()
ON_WM_RBUTTONDOWN()
ON_COMMAND(ID_VIEW_ZOOMIN, OnViewZoomin)
ON_COMMAND(ID_VIEW_ZOOMOUT, OnViewZoomout)
ON_COMMAND(ID_VIEW_ZOOMRECT, OnViewZoomrect)
ON_COMMAND(ID_VIEW_MOVE, OnViewMove)
ON_COMMAND(ID_VIEW_FULLSCREEN, OnViewFullscreen)
ON_WM_SETCURSOR()
ON_WM_LBUTTONUP()
	ON_COMMAND(ID_FILE_IMPORT, OnFileImport)
	ON_COMMAND(ID_DRAW_POINT, OnDrawPoint)
	ON_WM_ERASEBKGND()
	//}}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()

/////////////////////////////////////////////////////////////////////////////
// CDrawShapeView construction/destruction

CDrawShapeView::CDrawShapeView()
{
	// TODO: add construction code here

	//得到应用程序路径

	GetAppPath();

	m_xStart=0.0;
	m_yStart=0.0;
	blc=1.0;
	m_MapMode=1; //设定MM_TEXT映射模式
	m_PushNum=0;
	
	m_LineType=0;  //以下在View中设定的参数值将影响在画图中的颜色
	m_LineWide=1;
	m_ColorPen=3;
	m_ColorBrush=2;
	m_Color=1;
	m_bDelete=0;
	m_Layer=1;
	m_DrawType=0;
	
	//在画图过程中,存储按左键的坐标,因为不知道使用者
	//到底画出多大顶点的图形,设置为最大3000
	m_PointArray=new PointStruct[3000];//连续直线、多边形数组

	IsFirst = true;
	IsFirstFill = true;
	
	iWScreen = GetSystemMetrics(SM_CXSCREEN);
	iHScreen = GetSystemMetrics(SM_CYSCREEN);
//	m_XminIntersect = 0;
//	m_YminIntersect = 0;
//	m_XmaxIntersect = 0;
// 	m_YmaxIntersect = 0;
}

CDrawShapeView::~CDrawShapeView()
{
	delete[] m_PointArray;
}

BOOL CDrawShapeView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	
	return CView::PreCreateWindow(cs);
	
}
/////////////////////////////////////////////////////////////////////////////
// CDrawShapeView drawing

void CDrawShapeView::OnDraw(CDC* pDC)
{
	CDrawShapeDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

	//全局变量初始化
	xMinScreen = m_xStart;
	yMinScreen = m_yStart;
	xMaxScreen = xMinScreen + blc*m_wScreen;
	yMaxScreen = yMinScreen + blc*m_hScreen;

		
		CDC MemDC;				//首先定义一个显示设备对象
		CBitmap MemBitmap;		//定义一个位图对象
//		static bool IsFirst = true;
// 		static bool IsFirstFill = true;

		
		//随后建立与屏幕显示兼容的内存显示设备
		//这里我们就在内存中虚拟建造了DC
		




		MemDC.CreateCompatibleDC(NULL);
		//	MemDC.CreateCompatibleDC(pDC);
		
		//这时还不能绘图,因为没有地方画
		//下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
		//依附DC创建bitmap
		if(IsFirst == true)
		{
			m_MemBitmap.CreateCompatibleBitmap(pDC,iWScreen,iHScreen);

			IsFirst = false;

		}
		
		//将位图选入到内存显示设备中
		//只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
		
		CBitmap *pOldBit=MemDC.SelectObject(&m_MemBitmap);
		
		//先用背景色将位图清除干净,这里我用的是白色作为背景
		//你也可以用自己应该用的颜色
		if(IsFirstFill = true)
		{
			MemDC.FillSolidRect(0,0,iWScreen,iHScreen,RGB(255,255,255));
			IsFirstFill = false;
		}

//以下在MemDC中的位图上绘图
	
	//遍历所有图形元素并绘制 
	// 1-直线 2-连续直线或多边形区域 3-点
	for(int i=1; i<4; i++)
	{
		for(int j=0; j <=  pDoc->GetGraphUpperBound(i); j++)
		{
			pDoc->GetGraph(i,j)->Draw(&MemDC,0,0,m_Color);
		}
	}
	
//MemDC中绘图结束	
	
	//将内存(MemDC)中的图拷贝到屏幕上(pDC)进行显示
	pDC->BitBlt(0,0,iWScreen,iHScreen,&MemDC,0,0,SRCCOPY);
	
	//绘图完成后的清理
	
	MemDC.SelectObject(pOldBit);
//	MemBitmap.DeleteObject();	//清除位图
	MemDC.DeleteDC();			//清除DC	
	
	
}

/////////////////////////////////////////////////////////////////////////////
// CDrawShapeView printing

BOOL CDrawShapeView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CDrawShapeView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CDrawShapeView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CDrawShapeView diagnostics

#ifdef _DEBUG
void CDrawShapeView::AssertValid() const
{
	CView::AssertValid();
}

void CDrawShapeView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CDrawShapeDoc* CDrawShapeView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDrawShapeDoc)));
	return (CDrawShapeDoc*)m_pDocument;
}
#endif //_DEBUG


/////////////////////////////////////////////////////////////////////////////
// CDrawShapeView message handlers

//(Logical to Actual)
//逻辑坐标为int,实际坐标为float

void CDrawShapeView::LPtoAP(int x,int y,float* X,float* Y)
{
	*X=m_xStart+x*blc;
	if(m_MapMode==1)//MM_TEXT模式
		*Y=m_yStart+blc*(m_hScreen-y);
	else//其它模式
		*Y=m_yStart+blc*(m_hScreen+y);
}

//实际坐标到逻辑坐标转换
void CDrawShapeView::APtoLP(float x,float y,int* X,int* Y)
{
	*X=(int)((x-m_xStart)/blc);
	if(m_MapMode==1)
		*Y=m_hScreen-(int)((y-m_yStart)/blc);
	else
		*Y=(int)((y-m_yStart)/blc)-m_hScreen;
	
}

//逻辑数值到实际数值 (logicla value to actual value)
float CDrawShapeView::LVtoAV(int a_iInputval)
{
	return blc * a_iInputval;
}

//实际数值到逻辑数值
int CDrawShapeView::AVtoLV(float a_fInputval)
{
	return (int)(a_fInputval / blc);
}




//
//void CDrawShapeView::OutPutX(int x)
//{
//CString mystr;
//mystr.Format("%d",x);
//	AfxMessageBox(mystr);
//}

void CDrawShapeView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) 
{
	// TODO: Add your specialized code here and/or call the base class
	
	gpCDrawShapeView=this;
	
	CView::OnActivateView(bActivate, pActivateView, pDeactiveView);
}

void CDrawShapeView::OnSize(UINT nType, int cx, int cy) 
{
	CView::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	m_wScreen=cx;
	m_hScreen=cy;
	gHScreen = cx;
	gWScreen = cy;
}

void CDrawShapeView::OnTestDraw() 
{

	//	CPen  pen(2,1,RGB(128,128,0));
	//	CPen* pOldPen=clientDC.SelectObject(&pen);
	//
	//			clientDC.MoveTo(point_array[0]);
	//		for(int i=1;i<3;i++)
	//			clientDC.LineTo(point_array[i]);
	//
	//
	//		clientDC.SelectObject(pOldPen);
	
	//
	//	CDrawShapeDoc* pDoc = GetDocument();
	//
	//	int i=pDoc->GetGraphUpperBound(2);
	
	
//	CReadShapefile clsShapefile;
//	clsShapefile.OpenShapefile();
//	int n=clsShapefile.GetShapeType();
	
//	double x1,y1,x2,y2;
//	double dXcoord1;		
//	double dYcoord1;	
//	double dXcoord2;	
//	double dYcoord2;
//
//	PointStruct mypoint;
//	clsShapefile.GetMapBound(x1,y1,x2,y2);
//	clsShapefile.GetLine(&mypoint);
//	CString str;
//	str.Format("%f",mypoint.x);
//	AfxMessageBox(str);
//
//	
	
	
	
	
	
	
	
//	AfxGetMainWnd() ->ShowWindow(SW_MAXIMIZE);
	//使程序最大化.
	
}

void CDrawShapeView::OnDrawLine() 
{
	// TODO: Add your command handler code here
	m_PushNum=0;
	m_DrawType=1;//绘制直线
	
}
void CDrawShapeView::OnLButtonDown(UINT nFlags, CPoint point) 

{
	// TODO: Add your message handler code here and/or call default
	CDrawShapeDoc* pDoc=GetDocument();
	CClientDC clientDC(this);
//	int iWScreen,iHScreen;	//屏幕宽度、高度
//	iWScreen = GetSystemMetrics(SM_CXSCREEN);
//	iHScreen = GetSystemMetrics(SM_CYSCREEN);






	if(m_DrawType==1)//如果是绘制直线
	{
		float x1,y1,x2,y2;
//		static bool IsFirst = true;
//		static bool IsFirstFill = true;
		
		CDC MemDC;
		MemDC.CreateCompatibleDC(NULL);
/*
		//新建文档时,此时应该进入
		if(IsFirst == true) //只能创建兼容DC一次,否则程序终止
		{
			m_MemBitmap.CreateCompatibleBitmap(&clientDC,iWScreen,iHScreen);
			IsFirst = false;
		}
*/

		CBitmap* pOldBitmap = MemDC.SelectObject(&m_MemBitmap);	
/*
		if(IsFirstFill == true) //只填充空白位图一次
		{
			MemDC.FillSolidRect(0,0,iWScreen,iHScreen,RGB(255,255,255));
			IsFirstFill = false;

		}

*/
//
//		CBitmap* pOldBitmap = MemDC.SelectObject(&m_MemBitmap);	
//		if(IsFirst == true) //只创建兼容DC一次
//		{
//		//填充白色背景
//		MemDC.FillSolidRect(0,0,iWScreen,iHScreen,RGB(255,255,255));
//		}

		
		if(m_PushNum==0)
		{
			m_PushNum++;
			m_PointOrg=point;
			m_PointOld=point;
//			m_PointOrg.x =50;
//			m_PointOrg.y =50;
//			m_PointOld.x=0;
//			m_PointOld.y=0;
			SetCapture();
		}
		else
		{
			LPtoAP(m_PointOrg.x,m_PointOrg.y,&x1,&y1);
			LPtoAP(point.x,point.y,&x2,&y2);
			
			//增加到m_LineArray中并绘制该直线
			CLine* myline=pDoc->AddLine(m_ColorPen,m_ColorBrush,m_LineWide,m_LineType,
				m_Layer,gpCGraphPara->GetIdOnly(),m_bDelete,x1,y1,
				x2,y2);
			
			//以MemDC取代clientDC
			//不必遍历所有图形并绘制,因为每次只需绘制当前的图形
			//而且每次绘的都会保存在位图中,



			//在位图上绘制
			myline->Draw(&MemDC,0,0,m_Color);
/*		
				
	//遍历所有图形元素并绘制 
	// 1-直线 2-连续直线或多边形区域 3-点
	for(int i=1; i<4; i++)
	{
		for(int j=0; j <=  pDoc->GetGraphUpperBound(i); j++)
		{
			pDoc->GetGraph(i,j)->Draw(&MemDC,0,0,m_Color);
		}
	}

*/		
			clientDC.BitBlt(0,0,iWScreen,iHScreen,&MemDC,0,0,SRCCOPY);
			MemDC.SelectObject(pOldBitmap);
			MemDC.DeleteDC();
		

			m_PushNum=0;
			ReleaseCapture();
		}


	}
	else if(m_DrawType==2 || m_DrawType==3)//绘制连续直线或多边形区域,它们同是按下左键时记录各个点坐标
	{
		float x,y;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -