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

📄 digitalmapview.cpp

📁 VC++开发广州市交通运输干线
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// DigitalMapView.cpp : implementation of the CDigitalMapView class
//

#include "stdafx.h"
#include "DigitalMap.h"

#include "DigitalMapDoc.h"
#include "DigitalMapView.h"
#include "MainFrm.h"
#include "math.h"
#include "DataCompDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////////////////////////////////////////////////////
#define ID_CUR_ZOOMOUT	1
#define ID_CUR_ZOOMIN	2
#define ID_CUR_PAN		3
#define ID_CUR_PT_SLT	4
#define ID_CUR_RT_SLT	5
#define ID_CUR_CI_SLT	6
#define ID_CUR_RTZOOM	7
//////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// CDigitalMapView

IMPLEMENT_DYNCREATE(CDigitalMapView, CView)

BEGIN_MESSAGE_MAP(CDigitalMapView, CView)
	//{{AFX_MSG_MAP(CDigitalMapView)
	ON_WM_LBUTTONDOWN()
	ON_COMMAND(ID_ZOOM_IN, OnZoomIn)
	ON_COMMAND(ID_ZOOM_OUT, OnZoomOut)
	ON_COMMAND(ID_PAN, OnPan)
	ON_WM_SETCURSOR()
	ON_WM_LBUTTONUP()
	ON_COMMAND(ID_COME_BACK, OnComeBack)
	ON_WM_RBUTTONDOWN()
	ON_UPDATE_COMMAND_UI(ID_ZOOM_IN, OnUpdateZoomIn)
	ON_UPDATE_COMMAND_UI(ID_ZOOM_OUT, OnUpdateZoomOut)
	ON_UPDATE_COMMAND_UI(ID_PAN, OnUpdatePan)
	ON_UPDATE_COMMAND_UI(ID_COME_BACK, OnUpdateComeBack)
	ON_COMMAND(ID_POINT_SELECT, OnPointSelect)
	ON_UPDATE_COMMAND_UI(ID_POINT_SELECT, OnUpdatePointSelect)
	ON_COMMAND(ID_RECT_SELECT, OnRectSelect)
	ON_UPDATE_COMMAND_UI(ID_RECT_SELECT, OnUpdateRectSelect)
	ON_COMMAND(ID_CIRCLE_SELECT, OnCircleSelect)
	ON_UPDATE_COMMAND_UI(ID_CIRCLE_SELECT, OnUpdateCircleSelect)
	ON_WM_MOUSEMOVE()
	ON_COMMAND(ID_RT_ZOOM, OnRtZoom)
	ON_UPDATE_COMMAND_UI(ID_RT_ZOOM, OnUpdateRtZoom)
	ON_COMMAND(ID_DATA_COMP, OnDataComp)
	ON_WM_LBUTTONDBLCLK()
	ON_COMMAND(ID_REFRESH, OnRefresh)
	ON_COMMAND(ID_FILE_SAVE, OnFileSave)
	//}}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()

/////////////////////////////////////////////////////////////////////////////
// CDigitalMapView construction/destruction

CDigitalMapView::CDigitalMapView()
{
	// TODO: add construction code here
	m_nStaComeBk = 0;
	m_nStaZoomOut = 0;
	m_nStaZoomIn = 0;
	m_nStaPan = 0;
	m_nStaRTZoom = 0;

	m_nPTSlct = 0;
	m_nRTSlct = 0;
	m_nCISlct = 0;

	m_bLButtDown = 0;
}

CDigitalMapView::~CDigitalMapView()
{
}

BOOL CDigitalMapView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CDigitalMapView drawing

void CDigitalMapView::OnDraw(CDC* pDC)
{
	CDigitalMapDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if(pDoc->m_bMapLoad)
	{
		pDoc->m_cGeoMap.Draw(pDC);
	}
}

/////////////////////////////////////////////////////////////////////////////
// CDigitalMapView printing

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

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

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

/////////////////////////////////////////////////////////////////////////////
// CDigitalMapView diagnostics

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

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

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

/////////////////////////////////////////////////////////////////////////////
// CDigitalMapView message handlers

void CDigitalMapView::SetRoundRect(CGeoRect RoundRect)
{
	m_RoundRect = RoundRect;
}

void CDigitalMapView::GetRoundRect(CGeoRect &RoundRect)
{
	RoundRect = m_RoundRect;
}

void CDigitalMapView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) 
{
	// TODO: Add your specialized code here and/or call the base class
	CDigitalMapDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if(pDoc->m_bMapLoad==true)
	{
		//开始进行坐标映射
		CRect rc;
		GetClientRect(&rc);
		//获得视口矩形
		if(m_RoundRect.top-m_RoundRect.bottom)
		{
			int  nWidth = (m_RoundRect.right-m_RoundRect.left);//窗口大小
            int  nHeight = (m_RoundRect.top-m_RoundRect.bottom);
			pDC->SetMapMode(MM_ANISOTROPIC);            //映射模式
			pDC->SetViewportOrg(rc.right,rc.bottom);    //视口原点
			pDC->SetWindowOrg(m_RoundRect.right,m_RoundRect.bottom);//窗口原点
			pDC->SetViewportExt(rc.Width(),-rc.Height());    //视口宽、高
			pDC->SetWindowExt(nWidth,nHeight); //窗口宽高
		}
		else CView::OnPrepareDC(pDC, pInfo);
	}
	CView::OnPrepareDC(pDC, pInfo);
}

void CDigitalMapView::OnLButtonDown(UINT nFlags, CPoint point) 
{	
	CDigitalMapDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if(pDoc->m_bMapLoad)
	{
		CClientDC dc(this);
		dc.SetROP2(R2_NOTXORPEN);
		
		OnPrepareDC(&dc);
		//记录鼠标点击的位置(设备坐标)
		POINT mousepoint = point;
		
		//由设备坐标(客户区坐标)转换为逻辑坐标(窗口坐标)
		dc.DPtoLP(&mousepoint);

		m_bLButtDown = 1;
		if(ID_CUR_ZOOMOUT==m_nCurStatus)	//缩小
		{
			ZoomOut(1,mousepoint);
			Invalidate(true);
		}
		if(ID_CUR_RTZOOM==m_nCurStatus)		//矩形放大
		{
			
			//记录开始点
			m_rtZoom.left = m_rtZoom.right = mousepoint.x;
			m_rtZoom.top = m_rtZoom.bottom = mousepoint.y;
			
			//绘制拉框矩形
			dc.Rectangle(m_rtZoom.left,m_rtZoom.top,m_rtZoom.right,m_rtZoom.bottom);
		}
		//点漫游操作
        if(ID_CUR_PAN == m_nCurStatus)
		{
			//记录开始点
			m_rtZoom.left = mousepoint.x;
			m_rtZoom.top = mousepoint.y;
		}	
		//如果是点击的点选取操作
		if(ID_CUR_PT_SLT==m_nCurStatus)
		{
			CGeoPointXY cGeoPTXY;
			cGeoPTXY.X = mousepoint.x;
			cGeoPTXY.Y = mousepoint.y;
			//由当前点得到格网的位置
			int nHorID = 0;
			int nVerID = 0;
			pDoc->FromPTXYToGridID(cGeoPTXY,nHorID,nVerID);
			//得到当前点所在格网的地物数目
			int nGridGeoNums = pDoc->m_cGeoMap.m_cGeoGrid[nVerID][nHorID].m_vecGeoGdAtt.size();
			for(int i=0;i<nGridGeoNums;i++)
			{
				CGeoGridAttri cGridAttri;
				cGridAttri = pDoc->m_cGeoMap.m_cGeoGrid[nVerID][nHorID].m_vecGeoGdAtt.at(i);
				int nLyerIndex = cGridAttri.m_nLyerIndex;
				//得到当前地物所在层的索引号
				if(GEO_PT_TYPE==cGridAttri.m_nType)
				{
					//如果当前地物是点
					//得到这个点对象的指针
					CGeoLayers cGeoLyer = pDoc->m_cGeoMap.m_vecLayers.at(nLyerIndex);
					CGeoPoint cGeoPoint = cGeoLyer.m_vecPoint.at(cGridAttri.m_nPtIndex);
					CDC *pDC = GetDC();
					OnPrepareDC(pDC);
					pDC->SetBkMode(TRANSPARENT);//使当前无背景色
					CGeoPointXY ptXY;
					cGeoPoint.GetPointXY(ptXY);
					//
					COLORREF clrBrush;
					clrBrush = RGB((rand()%255),(rand()%255),(rand()%255));
					CBrush brush(HS_CROSS,clrBrush);
					CBrush *pOldBrush = pDC->SelectObject(&brush);
					cGeoPoint.Draw(pDC,cGeoLyer.GetDisplay(),4);
				//	pDC->Ellipse(ptXY.X-4,ptXY.Y-4,ptXY.X+4,ptXY.Y+4);
					pDC->SelectObject(pOldBrush);
					//在下面的属性输出框中显示当前点的属性信息
					CMainFrame* pMain=(CMainFrame*)AfxGetMainWnd();
					CDC *pEditDC = pMain->m_wndEdit.GetDC();
					//下面得到该点的一些必要信息
					CString strGeoType = "地物类型:点                ";
					CString strGeoLyer;
					CString strLyerCode;
					cGeoLyer.GetLayerName(strLyerCode);
					pDoc->FromCodeToLyName(strLyerCode,strLyerCode);
					strGeoLyer.Format("所属层:%s                    ",strLyerCode);
					CString strPTX;
					strPTX.Format("X:%f                             ",ptXY.X);
					CString strPTY;
					strPTY.Format("Y:%f                                                                                                                 ",ptXY.Y);
					CString strTmp;
					int nAttriCode;
					CString strContent;
					cGeoPoint.GetAttriCode(nAttriCode);
					pDoc->FromAttriCodeToContent(nAttriCode,strTmp);
					strContent.Format("地物属性:%s                  ",strTmp);
					//输出
					pEditDC->TextOut(0,0,strGeoType);
					pEditDC->TextOut(150,0,strGeoLyer);
					pEditDC->TextOut(350,0,strContent);
					pEditDC->TextOut(0,20,strPTX);
					pEditDC->TextOut(150,20,strPTY);
					break;
				}
				if(GEO_PL_TYPE==cGridAttri.m_nType)
				{
					//如果当前为线对象
					//得到这个线对象的指针
					CGeoLayers cGeoLyer = pDoc->m_cGeoMap.m_vecLayers.at(nLyerIndex);
					CGeoPolyline cGeoPL = cGeoLyer.m_vecPolyline.at(cGridAttri.m_nPtIndex);
					int nPTNums = cGeoPL.m_vecPolyPoint.size();
					CGeoPointXY *pGeoPTXY = new CGeoPointXY[nPTNums];
					for(int m=0;m<nPTNums;m++)
					{
						pGeoPTXY[m].X = cGeoPL.m_vecPolyPoint.at(m).X;
						pGeoPTXY[m].Y = cGeoPL.m_vecPolyPoint.at(m).Y;
					}
					//判断这条线是否经过该点
					if(ISPTInPLine(pGeoPTXY,nPTNums,cGeoPTXY))
					{
						CDC *pDC = GetDC();
						OnPrepareDC(pDC);
						COLORREF clrPen;
						clrPen = RGB((rand()%255),(rand()%255),(rand()%255));
						CPen pen(PS_DOT,1,clrPen);
						CPen *pOldPen = pDC->SelectObject(&pen);
						cGeoPL.Draw(pDC,cGeoLyer.GetDisplay());
						pDC->SelectObject(pOldPen);

						//在下面的属性输出框中显示当前点的属性信息
						CMainFrame* pMain=(CMainFrame*)AfxGetMainWnd();
						CDC *pEditDC = pMain->m_wndEdit.GetDC();
						//下面得到该点的一些必要信息
						CString strGeoType = "地物类型:线             ";
						CString strGeoLyer;
						CString strLyerCode;
						cGeoLyer.GetLayerName(strLyerCode);
						pDoc->FromCodeToLyName(strLyerCode,strLyerCode);
						strGeoLyer.Format("所属层:%s                            ",strLyerCode);
						CString strMinPTX;
						strMinPTX.Format("MinX:%f                             ",cGeoPL.m_rtMinRect.left);
						CString strMinPTY;
						strMinPTY.Format("MinY:%f                             ",cGeoPL.m_rtMinRect.bottom);
						CString strMaxPTX;
						strMaxPTX.Format("MaxX:%f                             ",cGeoPL.m_rtMinRect.right);
						CString strMaxPTY;
						strMaxPTY.Format("MaxY:%f                             ",cGeoPL.m_rtMinRect.top);
						CString strTmp;
						int nAttriCode;
						CString strContent;
						cGeoPL.GetAttriCode(nAttriCode);
						pDoc->FromAttriCodeToContent(nAttriCode,strTmp);
						strContent.Format("地物属性:%s                                               ",strTmp);
						//输出
						pEditDC->TextOut(0,0,strGeoType);
						pEditDC->TextOut(150,0,strGeoLyer);
						pEditDC->TextOut(350,0,strContent);
						pEditDC->TextOut(0,20,strMinPTX);
						pEditDC->TextOut(150,20,strMinPTY);
						pEditDC->TextOut(350,20,strMaxPTX);
						pEditDC->TextOut(500,20,strMaxPTY);
						break;
					}
				}
				if(GEO_PG_TYPE==cGridAttri.m_nType)
				{
					CGeoLayers cGeoLyer = pDoc->m_cGeoMap.m_vecLayers.at(nLyerIndex);
					CGeoPolygon cGeoPG = cGeoLyer.m_vecPolygon.at(cGridAttri.m_nPtIndex);
					CRect rtRect;
					rtRect.left = cGeoPG.m_rtMinRect.left;
					rtRect.bottom = cGeoPG.m_rtMinRect.bottom;
					rtRect.right = cGeoPG.m_rtMinRect.right;
					rtRect.top = cGeoPG.m_rtMinRect.top;
					if(rtRect.PtInRect(mousepoint))
					{
						AfxMessageBox("fsfs");
					}
					//
					CDC *pDC = GetDC();
					OnPrepareDC(pDC);
					COLORREF clrBrush;
					COLORREF clrPen;
					clrPen = RGB((rand()%255),(rand()%255),(rand()%255));
					CPen pen(PS_DOT,1,clrPen);
					CPen *pOldPen = pDC->SelectObject(&pen);
					clrBrush = RGB((rand()%255),(rand()%255),(rand()%255));
					CBrush brush(HS_CROSS,clrBrush);
					CBrush *pOldBrush = pDC->SelectObject(&brush);

					cGeoPG.Draw(pDC,cGeoLyer.GetDisplay());
					pDC->SelectObject(&pOldPen);
					pDC->SelectObject(&pOldBrush);

					//
					//在下面的属性输出框中显示当前点的属性信息
					CMainFrame* pMain=(CMainFrame*)AfxGetMainWnd();
					CDC *pEditDC = pMain->m_wndEdit.GetDC();
					//下面得到该点的一些必要信息
					CString strGeoType = "地物类型:面             ";
					CString strGeoLyer;
					CString strLyerCode;
					cGeoLyer.GetLayerName(strLyerCode);
					pDoc->FromCodeToLyName(strLyerCode,strLyerCode);
					strGeoLyer.Format("所属层:%s                            ",strLyerCode);
					CString strMinPTX;
					strMinPTX.Format("MinX:%f                             ",cGeoPG.m_rtMinRect.left);
					CString strMinPTY;
					strMinPTY.Format("MinY:%f                             ",cGeoPG.m_rtMinRect.bottom);
					CString strMaxPTX;
					strMaxPTX.Format("MaxX:%f                             ",cGeoPG.m_rtMinRect.right);
					CString strMaxPTY;
					strMaxPTY.Format("MaxY:%f                             ",cGeoPG.m_rtMinRect.top);
					CString strTmp;
					int nAttriCode;
					CString strContent;
					cGeoPG.GetAttriCode(nAttriCode);
					pDoc->FromAttriCodeToContent(nAttriCode,strTmp);
					strContent.Format("地物属性:%s                                               ",strTmp);
					//输出
					pEditDC->TextOut(0,0,strGeoType);
					pEditDC->TextOut(150,0,strGeoLyer);
					pEditDC->TextOut(350,0,strContent);
					pEditDC->TextOut(0,20,strMinPTX);
					pEditDC->TextOut(150,20,strMinPTY);
					pEditDC->TextOut(350,20,strMaxPTX);
					pEditDC->TextOut(500,20,strMaxPTY);
				//	break;
				}
			}
			//以上包括了线的选取和面的选取程序,但是面选取的是根据外接矩形完成
			//所以不是很准确,下面干脆直接判断
			//面判断
	/*		for(int x=0;x<pDoc->m_cGeoMap.m_vecLayers.size();x++)
			{
				CGeoLayers geoLyers = pDoc->m_cGeoMap.m_vecLayers.at(x);
				for(int y=0;y<geoLyers.m_vecPolygon.size();y++)
				{
					CGeoPolygon geoPolygon = geoLyers.m_vecPolygon.at(y);
					CGeoRect rtMinGeoRect;
					rtMinGeoRect = geoPolygon.m_rtMinRect;
					BOOL bPtInGeoRect = rtMinGeoRect.PtInGeoRect(mousepoint);
					if(bPtInGeoRect==true)
					{
						//记录它的层编号
					//	AfxMessageBox("fsda");
					}
				}
			}*/
		}
	}
	CView::OnLButtonDown(nFlags, point);
}

void CDigitalMapView::OnZoomIn() 
{
	CDigitalMapDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if(pDoc->m_bMapLoad)
	{
		m_nCurStatus = ID_CUR_ZOOMIN;
		//
		m_nStaZoomIn = 1;
		m_nStaZoomOut = 0;
		m_nStaPan = 0;
		m_nStaComeBk = 0;
		m_nStaRTZoom = 0;
	}
}

void CDigitalMapView::OnZoomOut() 
{
	CDigitalMapDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if(pDoc->m_bMapLoad)
	{
		m_nCurStatus = ID_CUR_ZOOMOUT;
		//
		m_nStaZoomIn = 0;
		m_nStaZoomOut = 1;
		m_nStaPan = 0;

⌨️ 快捷键说明

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