📄 digitalmapview.cpp
字号:
// 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 + -