📄 digitalmapdoc.cpp
字号:
// DigitalMapDoc.cpp : implementation of the CDigitalMapDoc class
//
#include "stdafx.h"
#include "DigitalMap.h"
#include "DigitalMapDoc.h"
#include "MainFrm.h"
#include "DigitalMapView.h"
#include "vector"
using namespace std;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDigitalMapDoc
IMPLEMENT_DYNCREATE(CDigitalMapDoc, CDocument)
BEGIN_MESSAGE_MAP(CDigitalMapDoc, CDocument)
//{{AFX_MSG_MAP(CDigitalMapDoc)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDigitalMapDoc construction/destruction
CDigitalMapDoc::CDigitalMapDoc()
{
// TODO: add one-time construction code here
m_bMapLoad = false;
m_bAttriLoad = false;
}
CDigitalMapDoc::~CDigitalMapDoc()
{
}
BOOL CDigitalMapDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CDigitalMapDoc serialization
void CDigitalMapDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
/////////////////////////////////////////////////////////////////////////////
// CDigitalMapDoc diagnostics
#ifdef _DEBUG
void CDigitalMapDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CDigitalMapDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDigitalMapDoc commands
void CDigitalMapDoc::OnFileOpen()
{
//打开数据文件
TCHAR *pszFile = new TCHAR[MAX_PATH * MAX_PATH];
memset(pszFile,0,sizeof(TCHAR)*MAX_PATH * MAX_PATH);
//config file dialog
CFileDialog dlg(TRUE,
NULL,
NULL,
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT |OFN_ALLOWMULTISELECT|OFN_ENABLESIZING ,
_T("数据文件(data.txt)|data.txt|All Files (*.*)|*.*||"),
NULL);
dlg.m_ofn.lpstrFile = pszFile;
dlg.m_ofn.nMaxFile = MAX_PATH*MAX_PATH;
vector<CString> vecFilePath;
if(dlg.DoModal()==IDOK) //依次取出文件路径
{
POSITION filePos = dlg.GetStartPosition();
while(NULL!=filePos)
{
vecFilePath.push_back(dlg.GetNextPathName(filePos));
}
CString strDataPath = vecFilePath.at(0);
//调用读数据文件
ReadData(strDataPath);
}
if(AfxMessageBox("是否继续打开属性文件",MB_OKCANCEL,0)==IDOK)
{
//看是否继续打开属性文件
CFileDialog dlgAttri(TRUE,"*.txt",NULL,OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT|OFN_OVERWRITEPROMPT,
"属性数据文件(code.txt)|code.txt|任意文件(*.*)|*.*||",NULL);
//点击ok按钮
if(dlgAttri.DoModal() == IDOK)
{
CString FileName=dlgAttri.GetPathName();
ReadAttri(FileName);
}
}
}
BOOL CDigitalMapDoc::ReadData(CString strDataPath)
{
//根据文件路径打开文件并读取
FILE *fData;
if((fData=fopen(strDataPath,"r"))==NULL)
{
AfxMessageBox("Can't Open!");
exit(0);
}
CMainFrame* pMain=(CMainFrame*)AfxGetMainWnd();
CDigitalMapView *pView = (CDigitalMapView *)pMain->GetActiveView();//获得View类的指针
//开始读入数据96506.0, 47955.0, 98347.0, 49511.0
CGeoRect RoundRect;
fscanf(fData,"%f,%f,%f,%f",&RoundRect.left,&RoundRect.bottom,&RoundRect.right,&RoundRect.top);
TRACE("\n%s",fData );
pView->SetRoundRect(RoundRect);
m_cGeoMap.m_rtMap = RoundRect;
//读入层数8
int iLyerNums;
fscanf(fData,"%d",&iLyerNums); TRACE("\n%s",fData );
for(int i=0;i<iLyerNums;i++)
{
// 新建一个层Layer
CGeoLayers cGeoLayer;
CString strLayerName;
fscanf(fData,"%s",strLayerName); TRACE("\n%s",strLayerName );//P
cGeoLayer.SetLayerName(strLayerName);
CString strGraType; //图形类型,point,polyline,polygon
//开始读入该层的点集Point 108
int iPointNums;
fscanf(fData,"%s %d",strGraType,&iPointNums); TRACE("\n%s",strGraType );
for(int x=0;x<iPointNums;x++)
{
//读入每一个点属性84000,坐标96636.1, 48206.6
int iAttriCode;
CGeoPointXY cGeoPointXY; //新建一个点point
fscanf(fData,"%d",&iAttriCode); TRACE("\n%s",fData );
fscanf(fData,"%f,%f",&cGeoPointXY.X,&cGeoPointXY.Y); TRACE("\n%s",fData );
CGeoPoint cGeoPoint(cGeoPointXY,iAttriCode);
cGeoLayer.m_vecPoint.push_back(cGeoPoint);
//将该层的该点的相关信息加入格网索引中去
AddPTIndexToGrid(i,x,cGeoPointXY);
}
//开始读入折线的集合
int iPolylineNums;
fscanf(fData,"%s %d",strGraType,&iPolylineNums); TRACE("\n%s",strGraType );
for(int y=0;y<iPolylineNums;y++)
{
//读入每一个折线的坐标及其属性
int iAttriCode;
int iPolyPointNums; //折线的属性码和折线上的点数
fscanf(fData,"%d",&iAttriCode); TRACE("\n%s",fData ); TRACE("\n%s",fData );
fscanf(fData,"%d",&iPolyPointNums); TRACE("\n%s",fData ); TRACE("\n%s",fData );
CGeoPointXY *polylinePt = new CGeoPointXY[iPolyPointNums];
//记录当前最小的X,Y和最大的X,Y
float fMinX = RoundRect.right;
float fMinY = RoundRect.top;
float fMaxX = RoundRect.left;
float fMaxY = RoundRect.bottom;
for(int z=0;z<iPolyPointNums;z++)
{
fscanf(fData,"%f,%f",&polylinePt[z].X,&polylinePt[z].Y); TRACE("\n%s",fData );
//判断得到最小最大的X和Y
if(polylinePt[z].X>fMaxX)fMaxX = polylinePt[z].X;
if(polylinePt[z].Y>fMaxY)fMaxY = polylinePt[z].Y;
if(polylinePt[z].X<fMinX)fMinX = polylinePt[z].X;
if(polylinePt[z].Y<fMinY)fMinY = polylinePt[z].Y;
}
CString strTmp;
fscanf(fData,"%s",strTmp);TRACE("\n%s",strTmp ); //忽略掉END_COOR标识行,数据读入完毕
//初始化对象
CGeoPolyline cGeoPolyline(polylinePt,iPolyPointNums,iAttriCode); TRACE("\n%s",fData );
cGeoPolyline.m_rtMinRect.bottom = fMinY;
cGeoPolyline.m_rtMinRect.left = fMinX;
cGeoPolyline.m_rtMinRect.right = fMaxX;
cGeoPolyline.m_rtMinRect.top = fMaxY;
//添加对象到容器中去
cGeoLayer.m_vecPolyline.push_back(cGeoPolyline);
//将该线的必要索引信息添加到格网索引中去
AddPLIndexToGrid(i,y,cGeoPolyline.m_rtMinRect);
if(polylinePt!=NULL)
{
delete[] polylinePt;
}
}
//开始读入面集合
int iPolygonNums;
fscanf(fData,"%s %d",strGraType,&iPolygonNums); TRACE("\n%s",strGraType );
for(int z=0;z<iPolygonNums;z++)
{
//读入每个面的坐标值和属性
int iAttriCode;
int iPolyPointNums; //面上的属性码和面上的点数
fscanf(fData,"%d",&iAttriCode); TRACE("\n%s",fData );
fscanf(fData,"%d",&iPolyPointNums); TRACE("\n%s",fData );
CGeoPointXY *polylinePt = new CGeoPointXY[iPolyPointNums];
//
//记录当前最小的X,Y和最大的X,Y
float fMinX = RoundRect.right;
float fMinY = RoundRect.top;
float fMaxX = RoundRect.left;
float fMaxY = RoundRect.bottom;
//
for(int p=0;p<iPolyPointNums;p++)
{
fscanf(fData,"%f,%f",&polylinePt[p].X,&polylinePt[p].Y);
//判断得到最小最大的X和Y
if(polylinePt[p].X>fMaxX)fMaxX = polylinePt[p].X;
if(polylinePt[p].Y>fMaxY)fMaxY = polylinePt[p].Y;
if(polylinePt[p].X<fMinX)fMinX = polylinePt[p].X;
if(polylinePt[p].Y<fMinY)fMinY = polylinePt[p].Y;
}
CString strTmp;
fscanf(fData,"%s",strTmp); TRACE("\n%s",strTmp ); //忽略掉END_COOR标识行,数据读入完毕
//初始化对象
CGeoPolygon cGeoPolygon(polylinePt,iPolyPointNums,iAttriCode);
cGeoPolygon.m_rtMinRect.bottom = fMinY;
cGeoPolygon.m_rtMinRect.left = fMinX;
cGeoPolygon.m_rtMinRect.right = fMaxX;
cGeoPolygon.m_rtMinRect.top = fMaxY;
//
cGeoLayer.m_vecPolygon.push_back(cGeoPolygon);
//将该线的必要索引信息添加到格网索引中去
AddPGIndexToGrid(i,z,cGeoPolygon.m_rtMinRect);
if(polylinePt!=NULL)
{
delete[] polylinePt;
}
}
//以上读完了一个层的点,线,面数据
m_cGeoMap.m_vecLayers.push_back(cGeoLayer);
}
m_bMapLoad = true;
pView->Invalidate(TRUE);
//添加图层到左边
HTREEITEM hti = pMain->m_wndTree.InsertItem(_T("地图图层"));
for(int i=0;i<m_cGeoMap.m_vecLayers.size();i++)
{
CString strCode;
m_cGeoMap.m_vecLayers.at(i).GetLayerName(strCode);
CString strLayerName;
FromCodeToLyName(strCode,strLayerName);
AddTreeItem(strLayerName,hti);
}
if(m_TreeViewImg==NULL)
m_TreeViewImg.Create(IDB_STATEIMG,13,1,RGB(255,255,255));
pMain->m_wndTree.SetImageList(&m_TreeViewImg,TVSIL_STATE);
pMain->m_wndTree.SetItemState(hti, INDEXTOSTATEIMAGEMASK(2), TVIS_STATEIMAGEMASK);
return true;
}
void CDigitalMapDoc::SetTitle(LPCTSTR lpszTitle)
{
// TODO: Add your specialized code here and/or call the base class
lpszTitle = "数字地图制图DigitalMap1.0";
CDocument::SetTitle(lpszTitle);
}
void CDigitalMapDoc::AddTreeItem(CString strLayerName,HTREEITEM hti)
{
CMainFrame* pMain=(CMainFrame*)AfxGetMainWnd();
HTREEITEM htiNext = pMain->m_wndTree.InsertItem(strLayerName,hti);
pMain->m_wndTree.SetItemState(htiNext, INDEXTOSTATEIMAGEMASK(2), TVIS_STATEIMAGEMASK);
}
void CDigitalMapDoc::FromCodeToLyName(CString strCode, CString &strLayerName)
{
//为图层代码与图层显示建立对照表
if(strCode=="P")
{
strLayerName = "独立地物符号";
return;
}
if(strCode=="B")
{
strLayerName = "建筑物";
return;
}
if(strCode=="R")
{
strLayerName = "道路";
return;
}
if(strCode=="T")
{
strLayerName = "地貌";
return;
}
if(strCode=="F")
{
strLayerName = "境界";
return;
}
if(strCode=="V")
{
strLayerName = "绿化植被";
return;
}
if(strCode=="H")
{
strLayerName = "水系";
return;
}
if(strCode=="C")
{
strLayerName = "图幅控制网";
return;
}
}
void CDigitalMapDoc::ReadAttri(CString strAttriPath)
{
//根据文件路径打开属性文件并读取
FILE *fData;
if((fData=fopen(strAttriPath,"r"))==NULL)
{
AfxMessageBox("Can't Open!");
exit(0);
}
int nAttriCode;
int nNums;
CString strLyerName;
CString strLyerContent;
for(;!feof(fData);)
{
fscanf(fData,"%d %d %s %s",&nAttriCode,&nNums,strLyerName,strLyerContent);
CGeoAttri cGeoAttri;
cGeoAttri.m_attriCode = nAttriCode;
cGeoAttri.m_nNumber = nNums;
cGeoAttri.m_strLyerName = strLyerName;
cGeoAttri.m_strContent = strLyerContent;
m_cGeoMap.m_vecAttri.push_back(cGeoAttri);
}
}
//由某个点的位置得到其所在格网的索引号
void CDigitalMapDoc::FromPTXYToGridID(CGeoPointXY cGeoPTXY, int &nHorID, int &nVerID)
{
//得到当前地图的大地坐标
CGeoRect rtMapRect = m_cGeoMap.m_rtMap;
float fMapDisX = rtMapRect.right-rtMapRect.left;
float fMapDisY = rtMapRect.top-rtMapRect.bottom; //地图的幅长和幅宽
float fGridX = fMapDisX/HOR_GRIDS;
float fGridY = fMapDisY/VER_GRIDS; //一个格网的宽度和长度
//分别表示当前点在X和Y方向上距离左下角点的距离
float fDifferX = cGeoPTXY.X - rtMapRect.left;
float fDifferY = cGeoPTXY.Y - rtMapRect.bottom;
nHorID = (int)(fDifferX/fGridX);
nVerID = (int)(fDifferY/fGridY);
}
void CDigitalMapDoc::AddPTIndexToGrid(int nLyerIndex, int nPtIndex, CGeoPointXY cGeoPTXY)
{
//由当前点坐标得到格网索引号
int nHorID = 0;
int nVerID = 0;
FromPTXYToGridID(cGeoPTXY,nHorID,nVerID);
//
CGeoGridAttri cGridAttri;
cGridAttri.m_nPtIndex = nPtIndex;
cGridAttri.m_nType = GEO_PT_TYPE;
cGridAttri.m_nLyerIndex = nLyerIndex;
//
m_cGeoMap.m_cGeoGrid[nVerID][nHorID].m_vecGeoGdAtt.push_back(cGridAttri);
}
//由第二次读入的属性文件,由属性编号得到属性中对应的内容
void CDigitalMapDoc::FromAttriCodeToContent(int nAttriCode, CString &strContent)
{
int nAttRecNums = m_cGeoMap.m_vecAttri.size(); //属性记录的条数
for(int i=0;i<nAttRecNums;i++)
{
if(nAttriCode==m_cGeoMap.m_vecAttri.at(i).m_attriCode)
{
strContent = m_cGeoMap.m_vecAttri.at(i).m_strContent;
break;
}
}
}
void CDigitalMapDoc::AddPLIndexToGrid(int nLyerIndex, int nPLIndex, CGeoRect rtPLRect)
{
//由当前矩形坐标得到格网索引号
int nLBHorID = 0; //左下角点
int nLBVerID = 0;
CGeoPointXY cGeoPTXY;
cGeoPTXY.X = rtPLRect.left;
cGeoPTXY.Y = rtPLRect.bottom;
FromPTXYToGridID(cGeoPTXY,nLBHorID,nLBVerID);
int nRBHorID = 0; //右下角点
int nRBVerID = 0;
cGeoPTXY.X = rtPLRect.right;
cGeoPTXY.Y = rtPLRect.bottom;
FromPTXYToGridID(cGeoPTXY,nRBHorID,nRBVerID);
int nLTHorID = 0; //左上
int nLTVerID = 0;
cGeoPTXY.X = rtPLRect.left;
cGeoPTXY.Y = rtPLRect.top;
FromPTXYToGridID(cGeoPTXY,nLTHorID,nLTVerID);
int nRTHorID = 0; //右上
int nRTVerID = 0;
cGeoPTXY.X = rtPLRect.right;
cGeoPTXY.Y = rtPLRect.top;
FromPTXYToGridID(cGeoPTXY,nRTHorID,nRTVerID);
//
CGeoGridAttri cGridAttri;
cGridAttri.m_nPtIndex = nPLIndex;
cGridAttri.m_nType = GEO_PL_TYPE;
cGridAttri.m_nLyerIndex = nLyerIndex;
for(int x=nLBVerID;x<nRTVerID;x++)
{
for(int y=nLBHorID;y<nRTHorID;y++)
{
m_cGeoMap.m_cGeoGrid[x][y].m_vecGeoGdAtt.push_back(cGridAttri);
}
}
}
void CDigitalMapDoc::AddPGIndexToGrid(int nLyerIndex, int nPGIndex, CGeoRect rtPGRect)
{
//由当前矩形坐标得到格网索引号
int nLBHorID = 0; //左下角点
int nLBVerID = 0;
CGeoPointXY cGeoPTXY;
cGeoPTXY.X = rtPGRect.left;
cGeoPTXY.Y = rtPGRect.bottom;
FromPTXYToGridID(cGeoPTXY,nLBHorID,nLBVerID);
int nRBHorID = 0; //右下角点
int nRBVerID = 0;
cGeoPTXY.X = rtPGRect.right;
cGeoPTXY.Y = rtPGRect.bottom;
FromPTXYToGridID(cGeoPTXY,nRBHorID,nRBVerID);
int nLTHorID = 0; //左上
int nLTVerID = 0;
cGeoPTXY.X = rtPGRect.left;
cGeoPTXY.Y = rtPGRect.top;
FromPTXYToGridID(cGeoPTXY,nLTHorID,nLTVerID);
int nRTHorID = 0; //右上
int nRTVerID = 0;
cGeoPTXY.X = rtPGRect.right;
cGeoPTXY.Y = rtPGRect.top;
FromPTXYToGridID(cGeoPTXY,nRTHorID,nRTVerID);
//
CGeoGridAttri cGridAttri;
cGridAttri.m_nPtIndex = nPGIndex;
cGridAttri.m_nType = GEO_PG_TYPE;
cGridAttri.m_nLyerIndex = nLyerIndex;
for(int x=nLBVerID;x<nRTVerID;x++)
{
for(int y=nLBHorID;y<nRTHorID;y++)
{
m_cGeoMap.m_cGeoGrid[x][y].m_vecGeoGdAtt.push_back(cGridAttri);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -