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

📄 map.cpp

📁 Viaual C++实战演练一书的源代码,对于C++程序员有实际的借鉴意义.
💻 CPP
字号:
#include "stdafx.h"
#include "map.h"
#include "demo3doc.h"
#include "resource.h"

//*******************************************
//*********** CMapLayer ********************
//*******************************************

CString CMapLayer::GetFirstPara(CString& str)
{
	int i, j;
	char* buf;

	buf = (char*)LPCTSTR(str);
	for(i=0;i<BUFSIZ - 1 && buf[i] == ' '; i++);
	for(j=i;j<BUFSIZ - 1 && buf[j] != ' '; j++);
	return str.Mid(i, j-i);
}

int CMapLayer::GetSecondPara(CString& str)
{
	int i, j;
	char* buf;

	buf = (char*)LPCTSTR(str);
	for(i=0;i<BUFSIZ - 1 && buf[i] == ' '; i++);//去除第一项前导空格
	for(;i<BUFSIZ - 1 && buf[i] != ' '; i++);//到第一项结束
	for(;i<BUFSIZ - 1 && buf[i] == ' '; i++);//去除第二项前导空格
	for(j=i;j<BUFSIZ - 1 && buf[j] != ' '; j++);
	return atoi(LPCTSTR(str.Mid(i, j-i)));
}

CMapLayer::CMapLayer(CDemo3Doc* pDoc, CArchive& ar)
{
	CString str, str1;
	int i, j, k;
	CMapObject* object;

	m_pDoc = pDoc;
	m_nMaxPoint = 0;
	m_bCanDraw = true;

	while ( ar.ReadString(str) )
	{
		str1=GetFirstPara(str);
		if(str1=="Region")
		{
			j=GetSecondPara(str);
			for(i=0;i<j;i++)
			{
				ar.ReadString(str);
				k = atoi(LPCTSTR(str));
				object = new CMapRegion(pDoc, ar, k);
				m_aObject.Add(object);
				m_nMaxPoint = m_nMaxPoint > object->m_nMaxPoint ? m_nMaxPoint : object->m_nMaxPoint;
			}
		}
		else if(str1=="Pline")
		{
			j=GetSecondPara(str);
			object = new CMapPLine(pDoc, ar, j);
			m_aObject.Add(object);
			m_nMaxPoint = m_nMaxPoint > object->m_nMaxPoint ? m_nMaxPoint : object->m_nMaxPoint;
		}
		else if(str1=="Text")
		{
			object = new CMapText(pDoc, ar);
			m_aObject.Add(object);
			m_nMaxPoint = m_nMaxPoint > object->m_nMaxPoint ? m_nMaxPoint : object->m_nMaxPoint;
		}
	};//while(true);
}

CMapLayer::~CMapLayer()
{
	int i;
	int j=m_aObject.GetSize();

	for(i=0; i<j; i++)
	{//删除全部海图图元
		delete m_aObject.GetAt(i);
	}

	m_aObject.RemoveAll();

}

void CMapLayer::Draw(CDC* pDC, long style)
{
	int i;
	int j = m_aObject.GetSize();

	for(i=0; i<j; i++)
	{
		CMapObject* object = m_aObject.GetAt(i);
		if(object->m_nStyle == style)
			object->Draw(pDC);
	}
}

//*******************************************
//*********** CMapObject ********************
//*******************************************

CMapObject::CMapObject()
{
	m_pData = NULL; 
	m_nColor = 0;
	m_fMinX = 180;
	m_fMinY = 90;
	m_fMaxX = -180;
	m_fMaxY = -90;
}

bool CMapObject::IsInView()
{
	long x1, y1, x2, y2;

	x1 = 0, y1 = 0;
	x2 = m_pDoc->m_nViewWidth, y2 = m_pDoc->m_nVeiwHeight;
	m_pDoc->DPtoLP(x1, y1);//转换为逻辑坐标
	m_pDoc->DPtoLP(x2, y2);//转换为逻辑坐标
	CRect rect1(x1, y1, x2, y2);

	m_pDoc->ConvToXY(m_fMinX, m_fMaxY, x1, y1);//转换为逻辑坐标
	m_pDoc->ConvToXY(m_fMaxX, m_fMinY, x2, y2);
	CRect rect2(x1, y1, x2, y2);

	CRect rect;

	return rect.IntersectRect(rect1, rect2);
}

//*******************************************
//*********** CMapPLine *********************
//*******************************************

CMapPLine::CMapPLine(CDemo3Doc* pDoc, CArchive& ar, int points)
{
	int i, j;
	char buf[BUFSIZ];
	float f1, f2;

	m_pData = new float[points*2];//申请数据空间
	m_nMaxPoint = points;//保存最大点数
	m_pDoc = pDoc;
	m_nStyle = IDS_PLINE;//保存图元类型

	for(i=0; i<points; i++)
	{//读各端点数据
		ar.ReadString(buf, BUFSIZ - 1);
		for(j=0; j<BUFSIZ - 1 && buf[j]==' '; j++);//跳过前导空格
		f1 = atof(buf+j);//经度
		*(m_pData+2*i) = f1;
		for(; j<BUFSIZ - 1 && buf[j]!=' '; j++);//跳过空格间隔
		f2 = atof(buf+j+1);//纬度
		*(m_pData+2*i+1) = f2;
		//保存对象边界值
		m_fMinX = m_fMinX < f1 ? m_fMinX : f1;
		m_fMinY = m_fMinY < f2 ? m_fMinY : f2;
		m_fMaxX = m_fMaxX > f1 ? m_fMaxX : f1;
		m_fMaxY = m_fMaxY > f2 ? m_fMaxY : f2;
	}
}

void CMapPLine::Draw(CDC* pDC)
{
	if((m_nMaxPoint < 2) | (!IsInView()))
		return;

	long* data = m_pDoc->m_pData;
	CPen pen(PS_SOLID, 1, m_nColor/* 此时 m_nColor = 0 */), *oldpen;
	
	m_pDoc->ConvToXYs(m_pData, data, m_nMaxPoint);//将经纬度坐标转换为直角坐标
	m_pDoc->LPtoDPs(data, m_nMaxPoint);//将逻辑坐标转换为显示坐标
	
	oldpen = pDC->SelectObject(&pen);//设置绘制笔颜色

	pDC->Polyline((LPPOINT)data, m_nMaxPoint);//画折线

	pDC->SelectObject(oldpen);//恢复DC缺省值
	//删除资源
	pen.DeleteObject();
}

//*******************************************
//*********** CMapRegion ********************
//*******************************************

CMapRegion::CMapRegion(CDemo3Doc* pDoc, CArchive& ar, int points)
{
	int i, j;
	char buf[BUFSIZ];
	float f1, f2;

	m_pData = new float[--points*2];
	m_nMaxPoint = points;
	m_pDoc = pDoc;
	m_nStyle = IDS_POLYGON;

	for(i=0; i<points; i++)
	{
		ar.ReadString(buf, BUFSIZ - 1);
		for(j=0; j<BUFSIZ - 1 && buf[j]==' '; j++);
		f1 = atof(buf+j);//经度
		*(m_pData+2*i) = f1;
		for(; j<BUFSIZ - 1 && buf[j]!=' '; j++);
		f2 = atof(buf+j+1);//纬度
		*(m_pData+2*i+1) = f2;
		//保存对象边界值
		m_fMinX = m_fMinX < f1 ? m_fMinX : f1;
		m_fMinY = m_fMinY < f2 ? m_fMinY : f2;
		m_fMaxX = m_fMaxX > f1 ? m_fMaxX : f1;
		m_fMaxY = m_fMaxY > f2 ? m_fMaxY : f2;
	}
	ar.ReadString(buf, BUFSIZ - 1);//读出最后一点
	ar.ReadString(buf, BUFSIZ - 1);//读Pen数据
	i = strlen(ar.ReadString(buf, BUFSIZ - 1));//读Brush数据
	for(i=0; i<BUFSIZ -1 && buf[i]!=','; i++);//检索第一个逗号(,)
	m_nColor = atoi(buf+i+1);//获得填充颜色
	//转换颜色位定义
	//由于MapInfo与Windows使用不同的位定义RGB颜色,必须转换
	int c_red = m_nColor & 0xff0000;//红色分量
	int c_blue = m_nColor & 0xff;//兰色分量
	m_nColor =  (m_nColor & 0xff00) + (c_red >> 16) + (c_blue << 16);
}

void CMapRegion::Draw(CDC* pDC)
{
	if((m_nMaxPoint < 2) | (!IsInView()))
		return;

	long* data = m_pDoc->m_pData;
	CPen pen(PS_SOLID, 1, m_nColor), *oldpen;
	CBrush brush(m_nColor), *oldbrush;
	
	m_pDoc->ConvToXYs(m_pData, data, m_nMaxPoint);
	m_pDoc->LPtoDPs(data, m_nMaxPoint);
	
	//设置DC笔和刷的颜色
	oldpen = pDC->SelectObject(&pen);
	oldbrush = pDC->SelectObject(&brush);

	pDC->Polygon((LPPOINT)data, m_nMaxPoint);

	//恢复DC设置
	pDC->SelectObject(oldpen);
	pDC->SelectObject(oldbrush);
	//删除资源
	pen.DeleteObject();
	brush.DeleteObject();
}

//*******************************************
//************* CMapText ********************
//*******************************************

CMapText::CMapText(CDemo3Doc* pDoc, CArchive& ar)
{
	int i, j;
	char buf[BUFSIZ];

	m_nMaxPoint = 2;
	m_pDoc = pDoc;
	m_nStyle = IDS_TEXT;

	ar.ReadString(buf, BUFSIZ - 1);//读需显示字符串
	for(i=0; i<BUFSIZ - 1 && buf[i] != '\"'; i++);//去掉前导空格和前引号
	for(j=++i; j<BUFSIZ - 1 && buf[j] != '\"'; j++);//去掉后引号
	buf[j] = '\0';
	m_strText = buf+i;

	ar.ReadString(buf, BUFSIZ - 1 );
	for(i=0; i<BUFSIZ - 1 && buf[i]==' '; i++);
	m_fMinX = atof(buf+i);//第一点经度

	for(; i<BUFSIZ - 1 && buf[i]!=' '; i++);
	m_fMinY = atof(buf + ++i);//第一点纬度

	for(; i<BUFSIZ - 1 && buf[i]!=' '; i++);
	m_fMaxX = atof(buf + ++i);//第二点经度

	for(; i<BUFSIZ - 1 && buf[i]!=' '; i++);
	m_fMaxY = atof(buf + ++i);//第二点纬度
}

void CMapText::Draw(CDC* pDC)
{
	long x1, y1;
	long x2, y2;
	long fontheight;

	//转换经纬度到屏幕坐标
	m_pDoc->ConvToXY(m_fMaxX, m_fMaxY, x2, y1);
	m_pDoc->ConvToXY(m_fMinX, m_fMinY, x1, y2);
	m_pDoc->LPtoDP(x1, y1);
	m_pDoc->LPtoDP(x2, y2);

	CRect rect(x1, y1, x2, y2);//定义字符输出区域
	//计算字符高度
	fontheight = rect.Width() * 2 / m_strText.GetLength();
	if((!fontheight) | (!IsInView()))
		return;

	CFont font, *oldfont;
	font.CreateFont(fontheight, 0, 0, 0, FW_NORMAL, false, false, false,
		DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
		DEFAULT_QUALITY, DEFAULT_PITCH, "宋体");//创建字体

	//设置DC字体和背景模式
	oldfont = pDC->SelectObject(&font);
	int oldbkmode;
	oldbkmode = pDC->SetBkMode(TRANSPARENT);
	
	pDC->TextOut(x1, y1, m_strText);

	pDC->SelectObject(oldfont);
	pDC->SetBkMode(oldbkmode);

	font.DeleteObject();
}

⌨️ 快捷键说明

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