|
作者:heheheh |
积分:13 |
手机:诺基亚7500p |
注册:2009-10-07 |
|
灵格斯下载下来到不成问题,直接到首页下载它的词库就行,都是.ld2格式的。.ld2文件转换成txt网上有方法:
以下是山东省气象局,赵玉金师傅的邮件的转载:
ld2文件是二进制文件,和读取txt、dat文件有区别,我没有用过vb,但是可以给你说一下用C语言读取文件的细节,希望对你有所帮助。
首先,你提到的txt,dat文件,这些是一般的文本文件,你可以用写字板之类的程序打开,但是ld2文件不能这样打开开,首先就是它有128个字节的数据头,所以你得查查用vb怎么读取二进制文件。你先读取那128个字节,其中有很多信息,你可以看看给你的程序的public.h文件,有两个变量要注意,就是这个ld2文件的行数和列数,如果这两个数据读出来是400*300,表示这个ld2文件所表示的图像信息有400行,300列,这就有120000个数据点,其中每个数据占两个字节,所以你想读第一个通道的数据,就要从第129个字节开始,一直读到128+240000个字节的地方,读取出来的数据全部除10,即是真实数据。读取第二个通道的数据从129+240000字节开始一直到128+240000+240000字节处,整个ld2文件中有多少通道,可以在128字节的数据头中读出来。
C的写法:
1.
int fp=open(file_path,mode...);
2.
read(fp,buffer,buffer_size);//这里先读取128字节,所以buffer长度也是128字节
3.
从数据头中取得相应的信息,比如卫星号,时间,数据大小,通道数等等
4.
read(fp,data_buffer,data_buffer_size);//这里正式开始读取数据信息,data_buffer大小要根据前面所说来的换算
5.
读取完毕以后你就可以保存成你想要的格式,比如dat、txt等等。
6.
close(fp);//关闭文件
LD2文件文件头,是128个字节。用VC++语言,表述如下:
/* 局地文件头记录结构,记录长度为128。*/
typedef struct tagLDFFileHeader
{
short int wFileID; // 文件标识 局地文件为"LA"
short int wSatelliteID; // 卫星标识, NOAA-14: 14, NOAA-12: 12 FY-1C:103 TERRA:1001
short int wOrbitNo; /* 轨道号 */
short int wUporDown; /* 升降轨标记, 1: 升轨, 0: 降轨 */
short int wYear; /* 年 */
short int wMonth; /* 月 */
short int wDay; /* 日 */
short int wHour; /* 时 */
short int wMinute; /* 分 */
short int wDayorNight; /* 白天黑夜标识, 0: 白天, 1: 黑夜 */
short int wChannelNums; /* 通道数*/
short int wProjectType; /* 投影方式, 0: 不投影, 1: 等角投影 2: 麦卡托投影, 3: 兰布托投影 */
/* 4: 极射赤面投影, 5: 艾尔伯斯投影 */
short int wWidth; /* 列数 */
short int wHeight; /* 行数 */
float fLonPrecision; /* 经度分辨率 -- 等角投影 */
/* x分辨率 -- 麦卡托、兰布托、极射赤面投影 */
float fLatPrecision; /* 纬度分辨率 -- 等角投影 */
/* y分辨率 -- 麦卡托、兰布托、极射赤面投影 */
float fStandardLat1; /* 标准纬度1 -- 麦卡托、兰布托、极射赤面投影有效 */
float fStandardLat2; /* 标准纬度2 -- 兰布托投影有效 */
float fEarthR; /* 地球半径 -- 麦卡托、兰布托、极射赤面投影有效 */
/* 对于艾尔伯斯投影,fMinLat, fMaxLat, fMinLon, fMaxLon */
/* 分别对应于最小y, 最大y, 最小x, 最大x */
float fMinLat; /* 最小纬度 */
float fMaxLat; /* 最大纬度 */
float fMinLon; /* 最小经度 */
float fMaxLon; /* 最大经度 */
float fStandardLon; /* 圆锥投影中心经线 (LAMBERT,POLAR,ALBERS) */
float fCenterLon; /* 图象中心点的经度 */
float fCenterLat; /* 图象中心点的纬度 */
BYTE bChIndex[40]; /* 通道索引 */
WORD wComposedDays; //已合成天数
WORD wVersion; //版本号
unsigned char NDVIOffSet;
bool bCloudMask;//WORD wBytes;
unsigned char ucFlag1;
//目前由于头文件过短。使用这个字符表示是否包含太阳天顶角,太阳方位角,高度,卫星天顶角,卫星方位角,地表特征
//第一位为太阳天顶角,1表示包含太阳天顶角数据,0表示没有
//第2位为太阳方位角,1表示包含太阳方位数据,0表示没有
//第3位为海拔高度,1表示包含海拔高度数据,0表示没有
//第4位为卫星天顶角,1表示包含卫星天顶角数据,0表示没有
//第5位为卫星方位角,1表示包含卫星方位角数据,0表示没有
//第6位为地表特征,1表示包含地表特征数据,0表示没有
unsigned char ucFlag2;
float fSkipLength;/* 局地文件头记录的后面填充字段长度 */
}tagLDFFileHeader;
其中,行列数对于读数据至关重要,经纬度画图的时候不可或缺。别的相对次要点。
读的时候。用指针,跳过128个字节,从129个字节开始读,按行列提取出每个通道的信息,然后加以保存。
注意,在matlab里面,通道数据格式是‘int16’,我在这里尝试了很久。
还有,缺省值为-2,不是NaN。
接下来画图的时候,直接读出来的数据是顺时针转了90度的了。
所以,最后一步是要翻转数据(也就是所谓的矩阵了)。
matlab语言为 ch1=fliplr(ch1');
就是把矩阵逆时针转90度。
到了现在,基本上的坎都已经过了。
剩下来的无非是对通道的简单运算,或是对通道进行一个季节变化的统计分析等工作。
%------------1.seperate the Channels in .ld2 files
fid1 = fopen('F:\Modis\read\TERRA_2007_01_21.ld2','r');
status=fseek(fid1,128,'bof'); %read from the 129 bytes
for i=1:36
stat1=fread(fid1,[3000,4000],'int16'); %be attantion the int16
stat1=fliplr(stat1'); %eddy the matrix
fid2=fopen(['F:\Modis\read\TERRA_2007_01_21_',num2str(i),'.dat'],'w');
fwrite(fid2,stat1,'float'); %write to purpose files
fclose(fid2);
end
fclose(fid1);
我只会VB,看不太懂,希望对你有帮助。
做出来了忘分享! |
|