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

📄 digitalmapdoc.cpp

📁 VC++开发广州市交通运输干线
💻 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 + -