typedef struct tagDEMFILEHEADER{ // 定义DEM数据的头文件格式 int map[6]; // 保留 int iDemY; // DEM格网Y方向上的点数 int iDemX; // DEM格网X方向上的点数 float sx; // X方向缩放系数 float sy; // Y方向缩放系数 float interval; // DEM格网点的采样间隔 } DEMFILEHEADER; |
DemHeader.iDemX = set.m_nXPoint; // 填充文件头 DemHeader.iDemY = set.m_nYPoint; DemHeader.interval = set.m_nInterval; // 选择待生成的DEM文件 CFileDialog fileDlg(FALSE, "*.dem", "*.dem", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "地形数据文件(*.dem)|*.dem||", NULL); if (fileDlg.DoModal() == IDOK) { // 申请DEM数据缓冲区 int* pData = new int[set.m_nWidthBytes * set.m_nYPoint + 100]; if (set.m_bUseRandom == FALSE) { BYTE R, G, B; // 24位图象将真彩数据转换为灰度数据保存 for (int i = 0; i < set.m_nYPoint; i++) { for (int j = 0; j < set.m_nXPoint; j++) { B = set.m_pData[i * set.m_nWidthBytes + j * 3]; G = set.m_pData[i * set.m_nWidthBytes + j * 3 + 1]; R = set.m_pData[i * set.m_nWidthBytes + j * 3 + 2]; pData[i * DemHeader.iDemX + j] = (int)((9798.0f * R + 19235.0f * G + 3735.0f * B) / 32768.0f); } } }else{ for (int i = 0; i < set.m_nXPoint * set.m_nYPoint; i++) // 用随机数填充DEM数据 pData[i] = (int)(rand() % set.m_nLimit); } CFile file; // 保存DEM数据到文件 file.Open(fileDlg.GetPathName(), CFile::modeCreate | CFile::modeReadWrite); if (pData != NULL) { file.Write((LPSTR)&DemHeader, sizeof(DemHeader)); file.WriteHuge((LPSTR)pData, DemHeader.iDemX * DemHeader.iDemY * sizeof(int)); } file.Close(); delete[] pData; } |
其中, set.m_nXPoint、set.m_nYPoint和set.m_nInterval分别为从图象获取得到的网格节点数和用户输入的网格间隔。这几个参数填充到DEMFILEHEADER 结构对象DemHeader中后将作为DEM文件头保存到新创建的DEM数据。set.m_pData指向的缓冲区保存有以RGB颜色值方式给出的各节点高程数据,经过换算后保存到DEM数据文件。
DEM数据文件的读取与保存
既然已经清楚DEM数据文件的存储格式,数据的读取就不是一件困难的事情了。下面先给出执行函数ReadDEM(CString sDemFile)的实现过程:
CFile file(sDemFile, CFile::modeRead); // 打开文件 DWORD length = file.GetLength(); // 得到文件长度 if (file.Read((LPSTR)&DemHeader, sizeof(DEMFILEHEADER)) != sizeof(DEMFILEHEADER)) { // 读入DEM头文件 MessageBox("文件头信息错误!","提示信息"); return false; } m_nDemX = DemHeader.iDemX; // 从文件头中取数据 m_nDemY = DemHeader.iDemY; m_nInterval = (int)DemHeader.interval; // 网络间隔 m_pDemX = new int[(m_nDemX + 1) * (m_nDemY + 1)]; // X坐标 m_pDemY = new int[(m_nDemX + 1) * (m_nDemY + 1)]; // Y坐标 m_pDemH = new int[length - sizeof(DEMFILEHEADER)]; // Z坐标 m_nHSize = length - sizeof(DEMFILEHEADER); m_nSumPointOfDem = m_nDemX * m_nDemY; // 网格总点数 int m_nSumFaceOfDem = 2 * (m_nDemX - 1) * (m_nDemY - 1); // 网格总面数 file.ReadHuge(m_pDemH, length - sizeof(DEMFILEHEADER)); // 读取数据 file.Close(); // 关闭文件 |
for (int i = 0; i < m_nDemY; i++) { for (int j = 0; j < m_nDemX; j++) { m_pDemX[m_nDemX * i + j] = m_nInterval * j - (m_nDemX / 2) * m_nInterval; m_pDemY[m_nDemX * i + j] = m_nInterval * i - (m_nDemY / 2) * m_nInterval; } } |
CFile file(m_sDEMFile, CFile::modeReadWrite); // 保存文件 file.Write((LPSTR)&DemHeader, sizeof(DemHeader)); file.WriteHuge((LPSTR)m_pDemH, DemHeader.iDemX * DemHeader.iDemY * sizeof(int)); file.Close(); |