一、实验名称
GIS制图
二、实验目的
通过本实验,完成经纬网、注记、人口专题图的绘制,掌握GIS制图的基本方法。
三、实验内容和要求
给定世界政区面状矢量数据(World.mif)及其属性数据(World.mid),在上次实验成果的基础上,利用C++代码完成经纬网、注记、人口专题图的绘制。
1)按照一定的经纬度间隔,绘制经纬网,完成函数CVBF_Map::DrawGrid(...)。
2)根据属性字段(如World.mif/mid文件中的字段CNTRY_NAME,或者北京行政区划.mif/mid文件中的字段Name),绘制注记,完成函数CVBF_Layer::DrawLabel(...)。
1 绘制经纬网
void CVBF_Map::DrawGrid(CDC* pDC)
{
CPen pen;
pen.CreatePen(PS_SOLID,1,RGB(255,97,0));
CPen* pOldPen = pDC->SelectObject(&pen);//使用画笔
//绘制经线
for (int L=-180; L<= 180;L+=30)
{
int nNumPoints = (180/15)+1;//经线跨度为180,每个点间隔15
int n=0;
POINT* pPointsClient = new POINT[nNumPoints];
for(int n=0; n<nNumPoints; n+=1)
{
for(int B =-90;B<=90;B+=15)
{
//地理区坐标>客户区坐标
int x, y;
GeoToClient(L,B,x,y);
pPointsClient[n].x = x;
pPointsClient[n].y = y;
n++;
//绘制经线度数
if(n==1)
{
int m=L;
CString strl;//定义一个字符串
strl.Format ("%d",m);//%取余,d输出十进制数
pDC->TextOut(pPointsClient[0].x,pPointsClient[0].y-30,strl);//标记经线的起点
}
}
}
//绘制折线
pDC->Polyline (pPointsClient, nNumPoints);
delete pPointsClient;
pDC->SelectObject (pOldPen);
}
//绘制纬线
for (int B = -90;B <= 90;B += 15)
{
int nNumPoints = (360/30)+1;
int n = 0;//一条纬线上点的个数,每条纬线跨度360,每个点的间隔为30
POINT* pPointsClient = new POINT[nNumPoints];
for(int n=0; n<nNumPoints; n+=1)
{
for(int L = -180;L <= 180;L += 30)
{
int x, y;
GeoToClient(L,B,x,y);
pPointsClient[n].x = x;
pPointsClient[n].y = y;
n++;
//绘制纬线度数
if(n==1)
{
int i=B;
CString str2;//定义一个字符串
str2.Format ("%d",i);
pDC->TextOut(pPointsClient[0].x + 15,pPointsClient[0].y,str2);
}
}
}
//绘制折线
pDC->Polyline (pPointsClient, nNumPoints);
delete pPointsClient;
pDC->SelectObject (pOldPen);
}
}
2 绘制注记
void CVBF_Layer::DrawLabel(CDC* pDC, CVBF_Feature* pFeature)
{
//获取该地理要素的坐标
const CVBF_Point2D& ptGeo = pFeature-> m_pGeometry->GetCenterPoint();
//地理坐标>客户区坐标
int x, y;
m_pMap->GeoToClient(ptGeo.x, ptGeo.y, x, y);
//输出注记,人口数大于某个值
if(pFeature->m_vFieldValues.size()>2)
{
std::string str = pFeature->m_vFieldValues [2];
int nPop = atoi( str.c_str ());
if (nPop >=0)
{
pDC->TextOut(x,y,pFeature->m_vFieldValues [1].c_str ());
}
}
}