手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>程序设计>C/C++>列表

GIS三维地景仿真设计之数字高程模型

来源:互联网 作者:西部数码 时间:2008-04-09
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!
  引言

  在上一篇文章中建立了OpenGL应用程序框架,为场景的绘制提供了环境支持。要绘制某一区域场地的场景自然需要通过对该区域各点坐标数据的建模来实现。由于这些点的坐标取值描述了该区域的基本地貌特征,因此建模后的场景能够无失真的再现该区域从而达到仿真的目的。但是在实际操作时不可能取该区域的全部点进行建模,无论是数据量还是运算速度都是不允许的。一般的做法是进行网格抽取,可以在该区域纵横方向各每隔1米、10米、100米或是1千米取一个点,以这些点的坐标值来模拟真实场景,网络抽取间隔应以抽取后的网格足够描述原区域地貌特征为准。由于网格间隔固定,因此网格的平面坐标能够很容易的推算出来而无须记录,真正有价值的是各点的高程数据,这种由高程数据组成的均匀间隔网格模型在GIS中通称为数字高程模型(DEM)。本文将就DEM数据的读取和生成进行重点介绍。

  DEM数据结构的定义

  DEM数据并没有统一的标准格式,常用的标准有美国地理DEM数据标准和日本DEM数据标准等多种,这类DEM数据定义的信息较多,而这里只使用了高程数据,如果使用上述格式标准则信息利用率太低。因此,这里将建立自己的DEM数据格式,并以此来存储某一区域的地景特征数据。如果要满足在引言中提到的DEM数据定义标准,至少需要定义网格的长、宽节点数、网格间隔以及各节点的高程数据。其中,各节点的高程数据以整型点阵数据方式存储记录,其余各参数可以作为文件头进行定义。由此可以定义数据结构DEMFILEHEADER来描述DEM文件头,该文件头除了定义上述几个必须字段外,还定义了一些保留字段以备将来扩展使用:

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;
  DEM数据文件的生成

  DEM数据文件的生成主要包括两部分:文件头的生成和网格数据的生成。如果数据量不大,可以用手工填表的方式将采集到的网格化高程数据写入到DEM数据文件。但在实际使用时,数据量往往是比较巨大的。应当采取某种自动化处理措施使其实用化。这里采取从位图导入高程数据的方式,通过前期处理将通过卫星遥感手段得到的某一地区的高程数据作为图象颜色值而以位图的形式给出,这样一来,只需要读取该位图信息,图象的宽度和高度就是DEM文件的X方向和Y方向的网格节点数,图象颜色值为高程数据,用户只需手工输入根据比例换算而来的网格间隔即可。下面这段代码是实现这部分功能的主要代码:

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坐标

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

热点关注
IDC资讯 虚拟主机 域名注册 托管租用 vps主机 智能建站
网站运营 建站经验 策划盈利 搜索优化 网站推广 免费资源
网站联盟 联盟新闻 联盟介绍 联盟点评 网赚技巧
行业资讯 业界动态 搜索引擎 网络游戏 门户动态 电子商务 广告传媒
网络编程 Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术 Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷 Internet Explorer
网页制作 FrontPages Dreamweaver Javascript css photoshop fireworks Flash
程序设计 Java技术 C/C++ VB delphi
网络知识 网络协议 网络安全 网络管理 组网方案 Cisco技术
操作系统 Win2000 WinXP Win2003 Mac OS Linux FreeBSD
返回首页 |关于我们 | 联系我们 | 付款方式 | 创业联盟 | 价格总览 | 资讯中心 | 友情链接 | 网站地图 | 招贤纳士 | RSS