
高程模型(.ded)文件结构
高程模型用来描述按网格划分的地形高程值,常在三维地形建模中被使用。
序号 | 结构类型 | 字节大小 | 说明 |
1 | ss_stdhdr | 8+4+8+8+26+26+52 | 文件头 |
2 | stats | 8+2+2+24 | 统计数据 |
3 | cell | 8*10 | 单元属性 |
…… | | | |
3+ stats.nCell | | | |
3+ stats.nCell +1 | Short* | 2*cell.fLatNum*cell.fLonNum | 高程数据 |
…… | | | |
1、 文件头
typedef struct{
long len; //文件头大小:128
char id[4]; //编号
char part[8]; //单位
char rev[8]; //版本信息
char create[26]; //创建人
char update[26]; //日期
char spare[52]; //空闲
}ss_stdhdr,LPStdHdr;
2、统计数据
typedef struct{
long nCell; //单元数,多为1
short iMinz; //最小高度
short iMaxz; //最大高度
char spare[24]; //空闲
}stats,LPStATS;
3、单元属性
typedef struct{
float flLatStart; //起始纬度
float flLatEnd; //终止纬度
float flLonStart; //起始经度
float flLonEnd; //终止经度
float flLatDelta; //纬度单位变化值
float flLonDelta; //经度单位变化值
float flLatNum; //纬度方向的高程数
float flLonNum; //经度方向的高程数
float flDeltaX; //flLatDelta/36000*1852
float flDeltaY; //flLonDelta/36000*1852*cos((flLatEnd- atStart)*3.1415926/360))
}cell_Hdr,LPCELLHDR;
4、高程数据
对应cell的高程数组,类型为short*,按先纬度方向存取
注意,ded模型文件采用big-endian方式存储的,在读取和写入时需要进行转换,具体请看下面的示例代码:
#define _ENDIAN_16( a, b ) ((byte*)(a))[0] = ((byte*)(b))[1],((byte*)(a))[1] = ((byte*)(b))[0];
#define ENDIAN_16( d ) { unsigned short tmp; _ENDIAN_16( &tmp, &(d) ); (d) = tmp; }
#define _ENDIAN_32( a, b ) ((byte*)(a))[0] = ((byte*)(b))[3], /
((byte*)(a))[1] = ((byte*)(b))[2], /
((byte*)(a))[2] = ((byte*)(b))[1], /
((byte*)(a))[3] = ((byte*)(b))[0];
#define ENDIAN_32( d ) { unsigned int tmp; _ENDIAN_32( &tmp, &(d) ); (d) = tmp; }
#define _ENDIAN_64( a, b ) ((byte*)(a))[0] = ((byte*)(b))[7], /
((byte*)(a))[1] = ((byte*)(b))[6], /
((byte*)(a))[2] = ((byte*)(b))[5], /
((byte*)(a))[3] = ((byte*)(b))[4], /
((byte*)(a))[4] = ((byte*)(b))[3], /
((byte*)(a))[5] = ((byte*)(b))[2], /
((byte*)(a))[6] = ((byte*)(b))[1], /
((byte*)(a))[7] = ((byte*)(b))[0];
#define ENDIAN_32r( d ) { float tmp; _ENDIAN_32( &tmp, &(d) ); (d) = tmp; }
#define ENDIAN_64( d ) { long tmp; _ENDIAN_64( &tmp, &(d) ); (d) = tmp; }
#define ENDIAN_64r( d ) { double tmp; _ENDIAN_64( &tmp, &(d) ); (d) = tmp; }void CDedHead::ReadFile(CString chName) //读文件
{
if(!m_fileDED.Open(chName,CFile::modeRead))
return;
int nn = m_fileDED.Read(&m_stdhdr,sizeof(ss_stdhdr));
m_stdhdr.len = GetDedLong(m_stdhdr.len);
nn = m_fileDED.Read(&m_stats,sizeof(stats));
m_stats.nCell = GetDedLong(m_stats.nCell);
m_stats.iMaxz = GetDedshort(m_stats.iMaxz);
m_stats.iMinz = GetDedshort(m_stats.iMinz);
for(int i = 0; i < m_stats.nCell; i++)
{
nn = m_fileDED.Read(&m_cell,sizeof(cell_Hdr));
m_cell.flLonNum = Ex32Float(m_cell.flLonNum);
m_cell.flLatNum = Ex32Float(m_cell.flLatNum);
}
int size = m_cell.flLonNum*m_cell.flLatNum;
m_pData = new short[size];
m_fileDED.Read(m_pData, sizeof(short)*size);
m_fileDED.Close();
}
unsigned long CDedHead::Ex32Int(unsigned long lv)
{
unsigned long *buf = &lv;
for(unsigned int i=0;i<4;i++)
{
ENDIAN_32(buf[i]);
}
return *buf;
}
unsigned short CDedHead::Ex16(unsigned short sv)
{
unsigned short *buf = &sv;
for(unsigned int i=0;i<2;i++)
{
ENDIAN_16(buf[i]);
}
return *buf;
}
float CDedHead::Ex32Float(float fv)
{
float *buf = &fv;
for(unsigned int i=0;i<4;i++)
{
ENDIAN_32r(buf[i]);
}
return *buf;
}
unsigned long CDedHead::GetDedLong(unsigned long lv)
{
unsigned long by1 = lv - (lv>>8)*256;
lv = lv>>8;
unsigned long by2 = lv - (lv>>8)*256;
lv = lv>>8;
unsigned long by3 = lv - (lv>>8)*256;
lv = lv>>8;
unsigned long by4 = lv - (lv>>8)*256;
unsigned long lRet = (unsigned long)by4;
lRet += (unsigned long)(by3*256);
lRet += unsigned long(by2*256*256);
lRet += unsigned long(by1*256*256*256);
return lRet;
}
unsigned short CDedHead::GetDedshort(unsigned short sv)
{
unsigned short by1 = sv - (sv>>8)*256;
sv = sv>>8;
unsigned short by2 = sv - (sv>>8)*256;
unsigned short lRet = (unsigned short)by2;
lRet += (unsigned short)(by1*256);
return lRet;
}