一、实验名称
矢量数据结构
二、实验目的
通过本实验,了解常见矢量数据结构,熟练掌握如何利用C++代码和GDI图形库绘制矢量地图要素。
三、实验内容和要求
给定世界城市点状矢量数据(WorldCities.mif)、世界政区面状矢量数据(World.mif)和中国政区面状矢量数据(China.mif),模仿点状数据的读取与绘制方法,利用C++代码完成面状矢量数据的读取与绘制。
1)构建面向对象的空间数据模型;
2)进一步熟悉Visual Studio 2010集成开发环境;
3)模仿函数CVBF_Layer::LoadMifFile()中对点状(Point)和线状(Line)要素的读取方式,完成对面状(Region)要素的读取;
4)模仿类CVBF_Layer中的函数DrawPoint(…)和DrawPolyline(…),完成函数DrawPolyPolygon(…) ,即面状要素的绘制。
1 读取面状矢量数据
// 读取多边形的个数
int Region = 0;//赋初始值
fscanf(fpMif, "%d", &Region);
if(Region <= 0) continue;
CVBF_Feature* pFeature = new CVBF_Feature(nNumColumns);//创建新的面状要素
// 读取该多边形点的个数
int nNumPoints = 0;
fscanf(fpMif, "%d", &nNumPoints);
if(nNumPoints <= 0) continue;//点数如果无效继续
CVBF_GeometryPolygon* pGeometry = new CVBF_GeometryPolygon();
pFeature->m_pGeometry = pGeometry;
// 读取每个点的经纬度坐标值
for(int i = 0; i<nNumPoints; i++)
{
CVBF_Point2D* pPoint = new CVBF_Point2D;
fscanf(fpMif, "%lf", &pPoint->x);
fscanf(fpMif, "%lf", &pPoint->y);
pGeometry->m_vPoints.push_back(pPoint);
}
pFeature->m_pGeometry = pGeometry;
// 记录该面
m_vFeatures.push_back(pFeature);
// 读取属性数据
LoadOneAttrFromMid(fpMid, nNumColumns, cDelimiter, pFeature);
// 读取下一个要素的数据类型对象,跳过pen节,smooth节, brush节
fscanf(fpMif, "%s", szKey);
ReadSegmentSkip(fpMif, szKey, "pen");
ReadSegmentSkip(fpMif, szKey, "smooth");
ReadSegmentSkip(fpMif, szKey, "brush");
2 绘制面状矢量数据
CVBF_GeometryPolygon* pGemetry=(CVBF_GeometryPolygon*)pFeature->m_pGeometry;
// 使用画笔
CPen pen;
pen.CreatePen(PS_SOLID,symbol.m_nBorderWidth,symbol.m_nFillMode);
CPen* pOldPen = pDC->SelectObject(&pen);
// 使用画刷并给画刷设置颜色
CBrush brush;
brush.CreateSolidBrush(RGB(120,180,200));
CBrush* pOldBrush = pDC->SelectObject(&brush);
int nNumPoints=pGemetry->m_vPoints.size();
// 每个多边形的客户区坐标串
POINT* pPointsClient = new POINT[nNumPoints];
for(int n=0; n<nNumPoints; n++)
{
CVBF_Point2D* pPoint=pGemetry->m_vPoints[n];//调出结构体数据
int x,y;
m_pMap->GeoToClient(pPoint->x,pPoint->y,x,y);
pPointsClient[n].x = x;
pPointsClient[n].y = y;
}
// 绘制边线
pDC->Polygon(pPointsClient,nNumPoints);
delete pPointsClient;
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);