本人刚学C/C++不到半年,然后想用C++来写点东西,于是便有了本文的内容。
himawari 系列卫星
himawari8是日本发射的在西太平洋赤道上空的新一代静止轨道气象卫星,配备了16个不同的波段和5个观测区(1:FLDK圆盘,2:JP日本区域高频,3:目标观测区,台风吧常称为机动观测区,4:校准用高频区,不开放,5:未开放高频区)可用于多种观测,本文主要提到的是第8号和第9号所用的HSD格式卫星数据。
数据可以在JAXA Himawari Monitor | Registration申请访问。
前期准备
要想读取文件那首先得了解结构。数据使用指南在以下链接可以下载:https://www.data.jma.go.jp/mscweb/en/himawari89/space_segment/hsd_sample/HS_D_users_guide_en_v13.pdfhttps://www.data.jma.go.jp/mscweb/en/himawari89/space_segment/hsd_sample/HS_D_users_guide_en_v13.pdf HSD为二进制存储的数据文件,文件分为12个块。块1:基本信息,块2:数据信息,块3:投影信息,块4:导航信息,块5:校准信息,块6:校准间信息,块7:段信息,块8:导航校正信息,块9:观测时间信息,块10:错误信息,块11:空白块,块12:数据,这里就不展开赘述。
程序设计
处理信息头的时候我们将先使用结构体来定义11个块。
typedef struct{
unsigned char BlockNum;
unsigned short BlockLen;
unsigned short HeaderNum;
char ByteOrder;
char SatName[17];
char ProName[17];
char ObsType1[5];
char ObsType2[3];
unsigned short TimeLine;
double ObsStartTime;
double ObsEndTime;
double FileCreationMjd;
unsigned HeaderLen;
unsigned DataLen;
unsigned char qflag1;
unsigned char qflag2;
unsigned char qflag3;
unsigned char qflag4;
char DataVer[33];
char FileName[129];
char Spare[41];
} Basic_info;
typedef struct{
unsigned char BlockNum;
unsigned short BlockLen;
unsigned short BitPix;
unsigned short nPix;
unsigned short nLin;
unsigned char comp;
char Spare[41];
}Data_info;
typedef struct{
unsigned char BlockNum;
unsigned short BlockLen;
double subLon;
unsigned cfac;
unsigned lfac;
float coff;
float loff;
double SatDis;
double eqtrRadius;
double polrRadius;
double projParam1;
double projParam2;
double projParam3;
double projParamSd;
unsigned short resampleKind;
unsigned short resampleSize;
char Spare[41];
} Proj_info;
typedef struct{
unsigned char BlockNum;
unsigned short BlockLen;
double navMjd;
double sspLon;
double sspLat;
double SatDis;
double nadirLon;
double nadirLat;
double SunPos_X;
double SunPos_Y;
double SunPos_Z;
double MoonPos_X;
double MoonPos_Y;
double MoonPos_Z;
char Spare[41];
} Navi_info;
typedef struct {
unsigned char BlockNum;
unsigned short BlockLen;
unsigned short Band;
double waveLen;
unsigned short bitPix;
unsigned short ErrorCount;
unsigned short OutCount;
double gain_cnt2rad;
double cnst_cnt2rad;
double rad2btp_c0;
double rad2btp_c1;
double rad2btp_c2;
double rad2btp_c3;
double btp2rad_c0;
double btp2rad_c1;
double btp2rad_c2;
double c; //光速 lightSpeed
double h; //普朗克常数 planckConst
double p; //黑体常数 bolzConst
double Spare[41];
double rad2albedo;
double Coeff_mjd;
double gain_cnt2rad_mod;
double cnst_cnt2rad_mod;
char SpareV[105];
} Calib_info;
typedef struct{
unsigned char BlockNum;
unsigned short BlockLen;
double gsicsCorr_C;
double gsicsCorr_C_er;
double gsicsCorr_1;
double gsicsCorr_1_er;
double gsicsCorr_2;
double gsicsCorr_2_er;
double gsicsBias;
double gsicsUncert;
double gsicsStscene;
double gsicsCorr_StrMJD;
double gsicsCorr_EndMJD;
char gsicsCorrInfo[65];
float gsicsUpperLimit;
float gsicsLowerLimit;
char gsicsFilename[129];
char Spare[129];
} InterCalib_info;
typedef struct{
unsigned char BlockNum;
unsigned short BlockLen;
char totalSegNum;
char segSeqNo;
unsigned short strLineNo;
char Spare[41];
} Segm_info;
typedef struct{
unsigned char BlockNum;
unsigned short BlockLen;
float RoCenterColumn;
float RoCenterLine;
double RoCorrection;
unsigned short correctNum;
unsigned short* lineNo;
float* columnShift;
float* lineShift;
char Spare[41];
} NaviCorr_info;
typedef struct{
unsigned char BlockNum;
unsigned short BlockLen;
unsigned short obsNum;
unsigned short* lineNo;
double* obsMJD;
char Spare[41];
} ObsTime_info;
typedef struct{
unsigned char BlockNum;
unsigned int BlockLen;
unsigned short errorNum;
unsigned short* lineNo;
unsigned short* errPixNum;
char Spare[41];
} Erro_info;
typedef struct{
unsigned char BlockNum;
unsigned short BlockLen;
char Spare[257];
} Spare;
随后我们使用一个类进行封装:
using namespace std;
class HSD
{private:
FILE* fp;
double planck_c1, planck_c2, lambda, effective_temperature, phi, re, r1, r2, r3, rn, x, y, Sd, Sn, S1, S2, S3, Sxy;
char byteFlag;
bool ER_FLAG,Read_State;
float c, l, version;
int byteOrder(void) {
int i = 1;
if (*((char*)&i)) return 0; /* Little */
else if (*((char*)&i + (sizeof(int) - 1))) return 1; /* Big */
else return -1;
}
void swapBytes(void* buf, int size, int nn){
char* ba, * bb, * buf2;
buf2 = (char*)buf;
while (nn--) {
bb = (ba = buf2) + size - 1;
do {
char a;
a = *ba;
*ba = *bb;
*bb = a;
} while (++ba < --bb);
buf2 += size;
}
}
public:
Basic_info basic;
Data_info data;
Proj_info proj;
Navi_info nav;
Calib_info calib;
InterCalib_info interCalib;
Segm_info seg;
NaviCorr_info navcorr;
ObsTime_info obstime;
Erro_info error;
Spare spare;
Correct_Table correct_table;
bool ReadData(char* filename);
bool lonlat_topixlin(double lon, double lat, double & pix, double & lin);
bool pixlin_to_lonlat( float pix, float lin, double & lon, double & lat);
double RadianceToTBB(unsigned short radiance);
double RadianceToReflectivity(unsigned short radia