源代码
头文件声明成员变量
RECT m_clientRECT;
CDC *m_Province_Boundary_memDC;
CBitmap *m_Province_Boundary_memBmp;
//最小经度与最大纬度
float m_minlon;
float m_maxlat;
//画图比例
int m_ratio;
oncreate函数定义变量,内存画图
GetParentFrame()->GetClientRect(&m_clientRECT);
m_clientDC = GetDC();
m_Province_Boundary_memBmp = new CBitmap();
m_Province_Boundary_memDC = new CDC();
m_Province_Boundary_memDC->CreateCompatibleDC(m_clientDC);
m_Province_Boundary_memBmp->CreateCompatibleBitmap(m_clientDC,memw,memh);
m_Province_Boundary_memDC->SelectObject(*m_Province_Boundary_memBmp);
m_minlon = 73;
m_maxlat = 54;
m_ratio = 3600 / 40;
画图函数
CString strFilePath;//shapefile文件路径
CString strName = _T("Province_Boundary.shp");//shapefile文件名
strFilePath.Format(_T(".\\Map\\%s"), strName);//shapefile文件放在项目目录创建的Map文件夹中
CPen pen(PS_SOLID, 2, clr);//创建画笔,2为线宽,clr是颜色
CPen *pen_Old = m_Province_Boundary_memDC->SelectObject(&pen);//选择画笔
FILE* fp = fopen(strFilePath, _T("rb"));
if (fp == NULL) {
AfxMessageBox(_T"打开shapefile文件失败");
exit(0);
}
//读取文件头
int fc; //File Code:9994
int ud; //Unused
int fl; //文件的实际长度
int vr; //版本号
int ft; //几何类型
//0 Null Shape 表示这个 Shapefile 文件不含坐标
//1 Point 表示 Shapefile 文件记录的是点状目标,但不是多点
//3 PolyLine 表示 Shapefile 文件记录的是线状目标
//5 Polygon 表示 Shapefile 文件记录的是面状目标
double xi; //空间数据所占空间范围的 X 方向最小值
double yi; //空间数据所占空间范围的 Y 方向最小值
double xa; //空间数据所占空间范围的 X 方向最大值
double ya; //空间数据所占空间范围的 Y 方向最大值
double zi; //空间数据所占空间范围的 Z 方向最小值
double za; //空间数据所占空间范围的 Z 方向最大值
double mi; //Measure最小值
double ma; //Meature最大值
fread(&fc, sizeof(int), 1, fp); //读取File Code
for(int i=0;i<5;i++) fread(&ud, sizeof(int), 1, fp); //读取Unused
fread(&fl, sizeof(int), 1, fp); //读取文件的实际长度
fread(&vr, sizeof(int), 1, fp); //读取版本号
fread(&ft, sizeof(int), 1, fp); //读取几何类型
fread(&xi, sizeof(double), 1, fp);
fread(&yi, sizeof(double), 1, fp);
fread(&xa, sizeof(double), 1, fp);
fread(&ya, sizeof(double), 1, fp);
fread(&zi, sizeof(double), 1, fp);
fread(&za, sizeof(double), 1, fp);
fread(&mi, sizeof(double), 1, fp);
fread(&ma, sizeof(double), 1, fp);
//读取实体内容
if(ft == 3||ft == 5){ //线类型或者面类型
int num; //记录序号
int len; //记录长度
while((fread(&num, sizeof(int), 1, fp) != 0)){ //逐条读记录
fread(&len, sizeof(int), 1, fp); //读取当前记录长度
int ftp; //当前记录类型记录
double area[4]; //当前记录坐标范围
int partnum; //当前记录包含的子线段/子环个数
int pointnum; //当前记录坐标点数
int *part; //每个子线段/子环的第一个坐标点在所有坐标中的位置
fread(&ftp, sizeof(int), 1, fp); //读ftp
for(int i = 0; i < 4; i++) fread(area + i, sizeof(double), 1, fp); //读area
fread(&partnum, sizeof(int), 1, fp); //读partnum
fread(&pointnum, sizeof(int), 1, fp); //读pointnum
part = new int[partnum]; //根据子线段/子环个数动态分配part数组内存
for(int i = 0; i < partnum; i++) fread(part + i, sizeof(int), 1, fp);
int pointnum1 = 0;//真实点数
for(int i = 0; i < partnum; i++){
if(i != partnum - 1) pointnum1 = part[i + 1] - part[i];//每个子环的长度 ,非最后一个环
else pointnum1 = pointnum - part[i]; //最后一个环
double *pointsx; //x坐标临时存储数组
double *pointsy; //y坐标临时存储数组
pointsx = new double[pointnum1]; //动态分配内存
pointsy = new double[pointnum1];
for(int j = 0; j < pointnum1; j++){
fread(pointsx + j, sizeof(double), 1, fp);
fread(pointsy + j, sizeof(double), 1, fp);
}
//非闭环(首尾两个点不一致),跳过
if(pointsx[0] != pointsx[pointnum1 - 1] || pointsy[0] != pointsy[pointnum1 - 1]){
delete []pointsx;
delete []pointsy;
continue;
}
for(int j = 0; j < pointnum1; j++){
pointsx[j] = (pointsx[j] - m_minlon) * m_ratio;
pointsy[j] = (m_maxlat - pointsy[j]) * m_ratio;
if(j > 0){
//此处在内存画布中画地图
m_Province_Boundary_memDC->MoveTo(pointsx[j - 1], pointsy[j - 1]);
m_Province_Boundary_memDC->LineTo(pointsx[j], pointsy[j]);
}
}
delete []pointsx;
delete []pointsy;
}
}
}
m_Province_Boundary_memDC->SelectObject(pen_Old);
DeleteObject(pen);
fclose(fp);
在客户区显示
CClientDC dc(this);
dc.BitBlt(0, 0, m_clientRECT.right, m_clientRECT.bottom, m_Province_Boundary_memDC, 0, 0, SRCCOPY);
注意
m_ratio; 决定地图大小
m_minlon; m_maxlat;两者确定左上角的经纬度