本人刚学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;  //光速 lightSpeeddouble           h;  //普朗克常数 planckConstdouble           p;  //黑体常数 bolzConstdouble          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 radiance);
};

随后来写读取部分的函数:

 bool HSD::ReadData(char* filename){int ii;fp = fopen(filename, "rb");if (fp == NULL){cout << "文件打开失败" << endl;ER_FLAG = true;return false;}else{Read_State = true;/*<block 1>*/if ((1 > fread(&basic.BlockNum, 1, 1, fp)) ||(1 > fread(&basic.BlockLen, 2, 1, fp)) ||(1 > fread(&basic.HeaderNum, 2, 1, fp)) ||(1 > fread(&basic.ByteOrder, 1, 1, fp)) ||(1 > fread(&basic.SatName, 16, 1, fp)) ||(1 > fread(&basic.ProName, 16, 1, fp)) ||(1 > fread(&basic.ObsType1, 4, 1, fp)) ||(1 > fread(&basic.ObsType2, 2, 1, fp)) ||(1 > fread(&basic.TimeLine, 2, 1, fp)) ||(1 > fread(&basic.ObsStartTime, 8, 1, fp)) ||(1 > fread(&basic.ObsEndTime, 8, 1, fp)) ||(1 > fread(&basic.FileCreationMjd, 8, 1, fp)) ||(1 > fread(&basic.HeaderLen, 4, 1, fp)) ||(1 > fread(&basic.DataLen, 4, 1, fp)) ||(1 > fread(&basic.qflag1, 1, 1, fp)) ||(1 > fread(&basic.qflag2, 1, 1, fp)) ||(1 > fread(&basic.qflag3, 1, 1, fp)) ||(1 > fread(&basic.qflag4, 1, 1, fp)) ||(1 > fread(&basic.DataVer, 32, 1, fp)) ||(1 > fread(&basic.FileName, 128, 1, fp)) ||(1 > fread(&basic.Spare, 40, 1, fp))){cout << "块1读取出现错误" << endl;ER_FLAG = true;return false;}if (basic.BlockLen != 282){byteFlag = 1;swapBytes(&basic.BlockLen, 2, 1);swapBytes(&basic.BlockNum, 2, 1);swapBytes(&basic.ObsStartTime, 8, 1);swapBytes(&basic.ObsEndTime, 8, 1);swapBytes(&basic.TimeLine, 2, 1);swapBytes(&basic.FileCreationMjd, 8, 1);swapBytes(&basic.HeaderLen, 4, 1);swapBytes(&basic.DataLen, 4, 1);}if (basic.BlockNum != 1 || basic.BlockLen != 282){cout << "块1读取出现错误" << endl;ER_FLAG = true;return false;}      /*</block 1>*/if (!ER_FLAG){/*<block 2>*/if ((1 > fread(&data.BlockNum, 1, 1, fp)) ||(1 > fread(&data.BlockLen, 2, 1, fp)) ||(1 > fread(&data.BitPix, 2, 1, fp)) ||(1 > fread(&data.nPix, 2, 1, fp)) ||(1 > fread(&data.nLin, 2, 1, fp)) ||(1 > fread(&data.comp, 1, 1, fp)) ||(1 > fread(&data.Spare, 40, 1, fp))){cout << "块2读取出现错误" << endl;ER_FLAG = true;return false;}if (byteFlag == 1){swapBytes(&data.BlockLen, 2, 1);swapBytes(&data.BitPix, 2, 1);swapBytes(&data.nPix, 2, 1);swapBytes(&data.nLin, 2, 1);}if (data.BlockNum != 2 || data.BlockLen != 50){cout << "块2读取出现错误" << endl;ER_FLAG = true;return false;}    /*</block 2>*//*<block 3>*/if ((1 > fread(&proj.BlockNum, 1, 1, fp)) ||(1 > fread(&proj.BlockLen, 2, 1, fp)) ||(1 > fread(&proj.subLon, 8, 1, fp)) ||(1 > fread(&proj.cfac, 4, 1, fp)) ||(1 > fread(&proj.lfac, 4, 1, fp)) ||(1 > fread(&proj.coff, 4, 1, fp)) ||(1 > fread(&proj.loff, 4, 1, fp)) ||(1 > fread(&proj.SatDis, 8, 1, fp)) ||(1 > fread(&proj.eqtrRadius, 8, 1, fp)) ||(1 > fread(&proj.polrRadius, 8, 1, fp)) ||(1 > fread(&proj.projParam1, 8, 1, fp)) ||(1 > fread(&proj.projParam2, 8, 1, fp)) ||(1 > fread(&proj.projParam3, 8, 1, fp)) ||(1 > fread(&proj.projParamSd, 8, 1, fp)) ||(1 > fread(&proj.resampleKind, 2, 1, fp)) ||(1 > fread(&proj.resampleSize, 2, 1, fp)) ||(1 > fread(&proj.Spare, 40, 1, fp))){cout << "块3读取出现错误" << endl;ER_FLAG = true;return false;}if (byteFlag == 1){swapBytes(&proj.BlockLen, 2, 1);swapBytes(&proj.subLon, 8, 1);swapBytes(&proj.cfac, 4, 1);swapBytes(&proj.lfac, 4, 1);swapBytes(&proj.coff, 4, 1);swapBytes(&proj.loff, 4, 1);swapBytes(&proj.SatDis, 8, 1);swapBytes(&proj.eqtrRadius, 8, 1);swapBytes(&proj.polrRadius, 8, 1);swapBytes(&proj.projParam1, 8, 1);swapBytes(&proj.projParam2, 8, 1);swapBytes(&proj.projParam3, 8, 1);swapBytes(&proj.projParamSd, 8, 1);swapBytes(&proj.resampleKind, 2, 1);swapBytes(&proj.resampleSize, 2, 1);}if (proj.BlockNum != 3 || proj.BlockLen != 127) {cout << "块3读取出现错误" << endl;ER_FLAG = true;return false;}    /*</block 3>*//*<block 4>*/if ((1 > fread(&nav.BlockNum, 1, 1, fp)) ||(1 > fread(&nav.BlockLen, 2, 1, fp)) ||(1 > fread(&nav.navMjd, 8, 1, fp)) ||(1 > fread(&nav.sspLon, 8, 1, fp)) ||(1 > fread(&nav.sspLat, 8, 1, fp)) ||(1 > fread(&nav.SatDis, 8, 1, fp)) ||(1 > fread(&nav.nadirLon, 8, 1, fp)) ||(1 > fread(&nav.nadirLat, 8, 1, fp)) ||(1 > fread(&nav.SunPos_X, 8, 1, fp)) ||(1 > fread(&nav.SunPos_Y, 8, 1, fp)) ||(1 > fread(&nav.SunPos_Z, 8, 1, fp)) ||(1 > fread(&nav.MoonPos_X, 8, 1, fp)) ||(1 > fread(&nav.MoonPos_Y, 8, 1, fp)) ||(1 > fread(&nav.MoonPos_Z, 8, 1, fp)) ||(1 > fread(&nav.Spare, 40, 1, fp))){cout << "块4读取出现错误" << endl;ER_FLAG = true;return false;}if (byteFlag == 1) {swapBytes(&nav.BlockLen, 2, 1);swapBytes(&nav.navMjd, 8, 1);swapBytes(&nav.sspLon, 8, 1);swapBytes(&nav.sspLat, 8, 1);swapBytes(&nav.SatDis, 8, 1);swapBytes(&nav.nadirLon, 8, 1);swapBytes(&nav.nadirLat, 8, 1);swapBytes(&nav.SunPos_X, 8, 1);swapBytes(&nav.SunPos_Y, 8, 1);swapBytes(&nav.SunPos_Z, 8, 1);swapBytes(&nav.MoonPos_X, 8, 1);swapBytes(&nav.MoonPos_Y, 8, 1);swapBytes(&nav.MoonPos_Z, 8, 1);}if (nav.BlockNum != 4 || nav.BlockLen != 139) {cout << "块4读取出现错误" << endl;ER_FLAG = true;return false;}   /*</block 4>*//*<block 5>*/if ((1 > fread(&calib.BlockNum, 1, 1, fp)) ||(1 > fread(&calib.BlockLen, 2, 1, fp)) ||(1 > fread(&calib.Band, 2, 1, fp)) ||(1 > fread(&calib.waveLen, 8, 1, fp)) ||(1 > fread(&calib.bitPix, 2, 1, fp)) ||(1 > fread(&calib.ErrorCount, 2, 1, fp)) ||(1 > fread(&calib.OutCount, 2, 1, fp)) ||(1 > fread(&calib.gain_cnt2rad, 8, 1, fp)) ||(1 > fread(&calib.cnst_cnt2rad, 8, 1, fp))){cout << "块5读取出现错误" << endl;ER_FLAG = true;return false;}if (byteFlag == 1) {swapBytes(&calib.BlockLen, 2, 1);swapBytes(&calib.Band, 2, 1);swapBytes(&calib.waveLen, 8, 1);swapBytes(&calib.bitPix, 2, 1);swapBytes(&calib.ErrorCount, 2, 1);swapBytes(&calib.OutCount, 2, 1);swapBytes(&calib.gain_cnt2rad, 8, 1);swapBytes(&calib.cnst_cnt2rad, 8, 1);}if ((calib.Band >= 7 && strstr(basic.SatName, "Himawari") != NULL) ||(calib.Band >= 2 && strstr(basic.SatName, "MTSAT-2") != NULL)){if ((1 > fread(&calib.rad2btp_c0, 8, 1, fp)) ||(1 > fread(&calib.rad2btp_c1, 8, 1, fp)) ||(1 > fread(&calib.rad2btp_c2, 8, 1, fp)) ||(1 > fread(&calib.btp2rad_c0, 8, 1, fp)) ||(1 > fread(&calib.btp2rad_c1, 8, 1, fp)) ||(1 > fread(&calib.btp2rad_c2, 8, 1, fp)) ||(1 > fread(&calib.c, 8, 1, fp)) ||(1 > fread(&calib.h, 8, 1, fp)) ||(1 > fread(&calib.p, 8, 1, fp)) ||(1 > fread(&calib.Spare, 40, 1, fp))){cout << "块5读取出现错误" << endl;ER_FLAG = true;return false;}if (byteFlag == 1){swapBytes(&calib.rad2btp_c0, 8, 1);swapBytes(&calib.rad2btp_c1, 8, 1);swapBytes(&calib.rad2btp_c2, 8, 1);swapBytes(&calib.btp2rad_c0, 8, 1);swapBytes(&calib.btp2rad_c1, 8, 1);swapBytes(&calib.btp2rad_c2, 8, 1);swapBytes(&calib.c, 8, 1);swapBytes(&calib.h, 8, 1);swapBytes(&calib.p, 8, 1);}}else {if (1 > fread(&calib.rad2albedo, 8, 1, fp)){cout << "块5读取出现错误" << endl;ER_FLAG = true;return false;}/* version 1.3 */if ((1 > fread(&calib.Coeff_mjd, 8, 1, fp)) ||(1 > fread(&calib.gain_cnt2rad_mod, 8, 1, fp)) ||(1 > fread(&calib.cnst_cnt2rad_mod, 8, 1, fp)) ||(1 > fread(&calib.SpareV, 80, 1, fp))){ER_FLAG = true;}if (byteFlag == 1){swapBytes(&calib.rad2albedo, 8, 1);}}if (calib.BlockNum != 5 || calib.BlockLen != 147){cout << "块5读取出现错误" << endl;ER_FLAG = true;return false;}    /*</block 5>*//*<block 6>*/version = atof(basic.DataVer);if (version > 1.1){    /* 1.2 */if ((1 > fread(&interCalib.BlockNum, 1, 1, fp)) ||(1 > fread(&interCalib.BlockLen, 2, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_C, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_1, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_2, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsBias, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsUncert, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsStscene, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_StrMJD, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_EndMJD, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsUpperLimit, 4, 1, fp)) ||(1 > fread(&interCalib.gsicsLowerLimit, 4, 1, fp)) ||(1 > fread(&interCalib.gsicsFilename, 128, 1, fp)) ||(1 > fread(&interCalib.Spare, 56, 1, fp))) {cout << "块6读取出现错误" << endl;ER_FLAG = true;return false;}if (byteFlag == 1){swapBytes(&interCalib.BlockLen, 2, 1);swapBytes(&interCalib.gsicsCorr_2, 8, 1);swapBytes(&interCalib.gsicsCorr_1, 8, 1);swapBytes(&interCalib.gsicsCorr_C, 8, 1);swapBytes(&interCalib.gsicsBias, 8, 1);swapBytes(&interCalib.gsicsUncert, 8, 1);swapBytes(&interCalib.gsicsStscene, 8, 1);swapBytes(&interCalib.gsicsCorr_StrMJD, 8, 1);swapBytes(&interCalib.gsicsCorr_EndMJD, 8, 1);swapBytes(&interCalib.gsicsUpperLimit, 4, 1);swapBytes(&interCalib.gsicsLowerLimit, 4, 1);}}else if (version > 1.0){   /* for version 1.1 */if ((1 > fread(&interCalib.BlockNum, 1, 1, fp)) ||(1 > fread(&interCalib.BlockLen, 2, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_C, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_C_er, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_1, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_1_er, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_2, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_2_er, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_StrMJD, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_EndMJD, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsUpperLimit, 4, 1, fp)) ||(1 > fread(&interCalib.gsicsLowerLimit, 4, 1, fp)) ||(1 > fread(&interCalib.gsicsFilename, 128, 1, fp)) ||(1 > fread(&interCalib.Spare, 56, 1, fp))) {cout << "块6读取出现错误" << endl;ER_FLAG = true;return false;}if (byteFlag == 1){swapBytes(&interCalib.BlockLen, 2, 1);swapBytes(&interCalib.gsicsCorr_2, 8, 1);swapBytes(&interCalib.gsicsCorr_2_er, 8, 1);swapBytes(&interCalib.gsicsCorr_1, 8, 1);swapBytes(&interCalib.gsicsCorr_1_er, 8, 1);swapBytes(&interCalib.gsicsCorr_C, 8, 1);swapBytes(&interCalib.gsicsCorr_C_er, 8, 1);swapBytes(&interCalib.gsicsCorr_StrMJD, 8, 1);swapBytes(&interCalib.gsicsCorr_EndMJD, 8, 1);swapBytes(&interCalib.gsicsUpperLimit, 4, 1);swapBytes(&interCalib.gsicsLowerLimit, 4, 1);}}else{ /* 1.0 and 0.0 */if ((1 > fread(&interCalib.BlockNum, 1, 1, fp)) ||(1 > fread(&interCalib.BlockLen, 2, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_C, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_C_er, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_1, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_1_er, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_2, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_2_er, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_StrMJD, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorr_EndMJD, 8, 1, fp)) ||(1 > fread(&interCalib.gsicsCorrInfo, 1, 64, fp)) ||(1 > fread(&interCalib.Spare, 128, 1, fp))) {cout << "块6读取出现错误" << endl;ER_FLAG = true;return false;}if (byteFlag == 1){swapBytes(&interCalib.BlockLen, 2, 1);swapBytes(&interCalib.gsicsCorr_2, 8, 1);swapBytes(&interCalib.gsicsCorr_2_er, 8, 1);swapBytes(&interCalib.gsicsCorr_1, 8, 1);swapBytes(&interCalib.gsicsCorr_1_er, 8, 1);swapBytes(&interCalib.gsicsCorr_C, 8, 1);swapBytes(&interCalib.gsicsCorr_C_er, 8, 1);swapBytes(&interCalib.gsicsCorr_StrMJD, 8, 1);swapBytes(&interCalib.gsicsCorr_EndMJD, 8, 1);}}if (interCalib.BlockNum != 6 || interCalib.BlockLen != 259){cout << "块6读取出现错误" << endl;ER_FLAG = true;return false;}   /*</block 6>*//*<block 7>*/if ((1 > fread(&seg.BlockNum, 1, 1, fp)) ||(1 > fread(&seg.BlockLen, 2, 1, fp)) ||(1 > fread(&seg.totalSegNum, 1, 1, fp)) ||(1 > fread(&seg.segSeqNo, 1, 1, fp)) ||(1 > fread(&seg.strLineNo, 2, 1, fp)) ||(1 > fread(&seg.Spare, 40, 1, fp))) {cout << "块7读取出现错误" << endl;ER_FLAG = true;return false;}if (byteFlag == 1){swapBytes(&seg.BlockLen, 2, 1);swapBytes(&seg.strLineNo, 2, 1);}if (seg.BlockNum != 7 || seg.BlockLen != 47){cout << "块7读取出现错误" << endl;ER_FLAG = true;return false;} /*</block 7>*//*<block 8>*/if ((1 > fread(&navcorr.BlockNum, 1, 1, fp)) ||(1 > fread(&navcorr.BlockLen, 2, 1, fp)) ||(1 > fread(&navcorr.RoCenterColumn, 4, 1, fp)) ||(1 > fread(&navcorr.RoCenterLine, 4, 1, fp)) ||(1 > fread(&navcorr.RoCorrection, 8, 1, fp)) ||(1 > fread(&navcorr.correctNum, 2, 1, fp))){cout << "块8读取出现错误" << endl;ER_FLAG = true;return false;}if (byteFlag == 1){swapBytes(&navcorr.BlockLen, 2, 1);swapBytes(&navcorr.RoCenterColumn, 4, 1);swapBytes(&navcorr.RoCenterLine, 4, 1);swapBytes(&navcorr.RoCorrection, 8, 1);swapBytes(&navcorr.correctNum, 2, 1);}navcorr.lineNo = (unsigned short*)calloc(navcorr.correctNum, sizeof(unsigned short));navcorr.columnShift = (float*)calloc(navcorr.correctNum, sizeof(float));navcorr.lineShift = (float*)calloc(navcorr.correctNum, sizeof(float));if (navcorr.lineNo == NULL || navcorr.columnShift == NULL || navcorr.lineShift == NULL) {cout << "块8内存分配出现错误" << endl;ER_FLAG = true;return false;}for (ii = 0; ii < navcorr.correctNum; ii++){if ((1 > fread(&navcorr.lineNo[ii], 2, 1, fp)) ||(1 > fread(&navcorr.columnShift[ii], 4, 1, fp)) ||(1 > fread(&navcorr.lineShift[ii], 4, 1, fp))) {cout << "块8读取出现错误" << endl;ER_FLAG = true;return false;}}if ((1 > fread(&navcorr.Spare, 40, 1, fp))) {cout << "块8读取出现错误" << endl;ER_FLAG = true;return false;}if (byteFlag == 1){swapBytes(&navcorr.lineNo[0], 2, navcorr.correctNum);swapBytes(&navcorr.columnShift[0], 4, navcorr.correctNum);swapBytes(&navcorr.lineShift[0], 4, navcorr.correctNum);}if (navcorr.BlockNum != 8){cout << "块8读取出现错误" << endl;ER_FLAG = true;return false;}   /*</block 8>*//*<block 9>*/if ((1 > fread(&obstime.BlockNum, 1, 1, fp)) ||(1 > fread(&obstime.BlockLen, 2, 1, fp)) ||(1 > fread(&obstime.obsNum, 2, 1, fp))){cout << "块9读取出现错误" << endl;ER_FLAG = true;;return false;}if (byteFlag == 1){swapBytes(&obstime.BlockLen, 2, 1);swapBytes(&obstime.obsNum, 2, 1);}obstime.lineNo = (unsigned short*)calloc(obstime.obsNum, sizeof(unsigned short));obstime.obsMJD = (double*)calloc(obstime.obsNum, sizeof(double));if (obstime.lineNo == NULL || obstime.obsMJD == NULL){cout << "块9内存分配出现错误" << endl;ER_FLAG = true;return false;}for (ii = 0; ii < obstime.obsNum; ii++){if ((1 > fread(&obstime.lineNo[ii], 2, 1, fp)) ||(1 > fread(&obstime.obsMJD[ii], 8, 1, fp))){cout << "块9读取出现错误" << endl;ER_FLAG = true;return false;}}if ((1 > fread(&obstime.Spare, 40, 1, fp))){cout << "块9读取出现错误" << endl;ER_FLAG = true;return false;}if (byteFlag == 1){swapBytes(&obstime.lineNo[0], 2, obstime.obsNum);swapBytes(&obstime.obsMJD[0], 8, obstime.obsNum);}if (obstime.BlockNum != 9){cout << "块9读取出现错误" << endl;ER_FLAG = true;return false;}   /*</block 9>*//*<block 10>*/if ((1 > fread(&error.BlockNum, 1, 1, fp)) ||(1 > fread(&error.BlockLen, 4, 1, fp)) ||(1 > fread(&error.errorNum, 2, 1, fp))) {cout << "块10读取出现错误" << endl;ER_FLAG = true;return false;}if (byteFlag == 1) {swapBytes(&error.BlockLen, 4, 1);swapBytes(&error.errorNum, 2, 1);}if (error.errorNum >= 1){error.lineNo = (unsigned short*)calloc(error.errorNum, sizeof(unsigned short));error.errPixNum = (unsigned short*)calloc(error.errorNum, sizeof(unsigned short));if (error.lineNo == NULL ||error.errPixNum == NULL){cout << "块10内存分配出现错误" << endl;ER_FLAG = true;return false;}for (ii = 0; ii < error.errorNum; ii++) {if ((1 > fread(&error.lineNo[ii], 2, 1, fp)) ||(1 > fread(&error.errPixNum[ii], 2, 1, fp))) {cout << "块10读取出现错误" << endl;ER_FLAG = true;return false;}}}if ((1 > fread(&error.Spare, 40, 1, fp))) {cout << "块10读取出现错误" << endl;ER_FLAG = true;return false;}if (byteFlag == 1) {swapBytes(&error.lineNo[0], 2, error.errorNum);swapBytes(&error.errPixNum[0], 2, error.errorNum);}if (error.BlockNum != 10) {cout << "块10读取出现错误" << endl;ER_FLAG = true;return false;}   /*</block 10>*//*<block 11>*/if ((1 > fread(&spare.BlockNum, 1, 1, fp)) ||(1 > fread(&spare.BlockLen, 2, 1, fp)) ||(1 > fread(&spare.Spare, 256, 1, fp))) {cout << "块11读取出现错误" << endl;ER_FLAG = true;}if (byteFlag == 1) {swapBytes(&spare.BlockLen, 2, 1);}if (spare.BlockNum != 11 || spare.BlockLen != 259) {cout << "块11读取出现错误" << endl;ER_FLAG = true;return false;}   /*</block 11>*/}}return true;}

基本数据读取完成,那么接下来完成以下数据使用要用到的函数(块12的数据结构为字节长度为2的无符号整数,限于篇幅,读取代码自行研究):

bool HSD::lonlat_topixlin(double lon, double lat, double & pix, double & lin){if (!Read_State){cout << "请先读取文件" << endl;return false;}if (!ER_FLAG){pix = -9999.0;lin = -9999.0;/*----------------------------------------------------------------------*/if (lat < -90 || lat>90)return 0;while (lon > 180.0)lon -= 360.0;while (lon < -180.0)lon += 360.0;/*----------------------------------------------------------------------*/lon = lon * DEGTORAD;lat = lat * DEGTORAD;phi = atan(proj.projParam2 * tan(lat));re = (proj.polrRadius) /sqrt(1 - proj.projParam1 * cos(phi) * cos(phi));r1 =proj.SatDis - re * cos(phi)* cos(lon - proj.subLon * DEGTORAD);r2 = -re * cos(phi)* sin(lon - proj.subLon * DEGTORAD);r3 = re * sin(phi);/*----------------------------------------------------------------------*/if (0 < (r1 * (r1 - proj.SatDis) + (r2 * r2) + (r3 * r3)))return false;/*----------------------------------------------------------------------*/rn = sqrt(r1 * r1 + r2 * r2 + r3 * r3);//cout <<rn << endl;x = atan2(-r2, r1) * RADTODEG;y = asin(-r3 / rn) * RADTODEG;c = proj.coff + x * SCLUNIT * proj.cfac;l = proj.loff + y * SCLUNIT * proj.lfac;pix = c;lin = l;return true;}return false;} //经纬度到像素坐标
bool HSD::pixlin_to_lonlat( float pix, float lin, double & lon, double & lat){if (!Read_State){cout << "请先读取文件" << endl;return false;}if (!ER_FLAG){c = pix;l = lin;if (c >= data.nPix) {c -= data.nPix;l++;};x = DEGTORAD * (c - proj.coff) / (SCLUNIT * proj.cfac);y = DEGTORAD * (l - proj.loff) / (SCLUNIT * proj.lfac);Sd = (proj.SatDis * cos(x) * cos(y)) * (proj.SatDis * cos(x) * cos(y)) - (cos(y) * cos(y) + proj.projParam3 * sin(y) * sin(y)) * proj.projParamSd;/*----------------------------------------------------------------------*/if (Sd < 0)return false;else Sd = sqrt(Sd);/*----------------------------------------------------------------------*/Sn = (proj.SatDis * cos(x) * cos(y) - Sd) / (cos(y) * cos(y) + proj.projParam3 * sin(y) * sin(y));S1 = proj.SatDis - (Sn * cos(x) * cos(y));S2 = Sn * sin(x) * cos(y);S3 = -Sn * sin(y);Sxy = sqrt(S1 * S1 + S2 * S2);lon = RADTODEG * atan2(S2, S1) + proj.subLon;lat = RADTODEG * atan(proj.projParam3 * S3 / Sxy);while (lon > 180.0)lon = lon - 360.0;while (lon < -180.0)lon = lon + 360.0;return true;}return false;}//像素坐标到经纬度
 double HSD::RadianceToTBB(unsigned short radiance){if (!Read_State){cout << "请先读取文件" << endl;return -9999;}if (!ER_FLAG){//radiance= radiance *calib.gain_cnt2rad + calib.cnst_cnt2rad;//lambda = calib.waveLen / 1000000.0;double rad;lambda =calib.waveLen / 1000000;rad = (radiance * calib.gain_cnt2rad + calib.cnst_cnt2rad) * 1000000;planck_c1 =  2.0 * calib.h *pow(calib.c, 2.0) /pow(lambda, 5.0);planck_c2 = calib.h *calib.c /calib.p / lambda;if (rad > 0) {effective_temperature = planck_c2 / log((planck_c1 / rad) + 1.0);return calib.rad2btp_c0 + calib.rad2btp_c1 * effective_temperature + calib.rad2btp_c2 * pow(effective_temperature, 2.0);}else {return -9999;}}return -9999;}//原始数据值到亮温
double RadianceToReflectivity(unsigned short radiance){if (!Read_State){cout << "请先读取文件" << endl;return -9999;}if (!Read_State){cout << "请先读取文件" << endl;return -9999;}if (!ER_FLAG){if (version >= 1.3) return calib.rad2albedo * (radiance * calib.gain_cnt2rad_mod + calib.cnst_cnt2rad_mod) * 100;else return calib.rad2albedo * (radiance * calib.gain_cnt2rad + calib.cnst_cnt2rad) * 100;}return -9999;}//原始数值到反射率

后期处理

后期处理比如数据的可视化就不在这详细展开了,本人使用了opencv来绘制图像,绘制的效果如下:

当然的要是你技术够硬,你也可以试试其他的合成方案以及拓展功能,发挥你们的创造力吧!

使用C++对himawari8(9)卫星数据的读取相关推荐

  1. matlab读取grib2数据,matlab读取grib2数据

    2018 基于通用模型的 GRIB 格式数据读取技术 王兵,李杰 (1. 南京航空航天大学 民航学院,江苏 南京 211106;2. 国家空管飞行流量技术重点实验室,江苏 南京 211106) 摘要: ...

  2. 卫星数据现已加入 Azure 豪华套餐,在太空向女神表个白?

    近日,微软特别项目研究小组刚刚宣布把2年前沉入苏格兰北部冰冷海底的小型水下数据中心打捞上岸,这个像缩小版"潜水艇"的数据中心里有 864 台服务器.27.6 PB的数据存储.潜过水 ...

  3. envi反演水质参数_科技前沿基于GOCI静止水色卫星数据的长江口及邻近海域Kd(490)遥感反演及其在机载激光测深预评估中的应用...

    点击上方"溪流之海洋人生"即可订阅哦 长江是我国的第一大河流,每年输入东海的悬浮泥沙含量可达1.81亿t(据大通站2000-2011年输沙量资料),巨量的悬浮泥沙在口门堆积,造成长 ...

  4. 使用GDAL工具对FY3系列卫星数据进行校正

    本文档主要对如何使用GDAL提供的工具对FY3系列卫星数据进行校正处理.FY3系列卫星提供的数据一般是以HDF5格式下发,一个典型的FY3A和FY3B的数据文件名如下: FY3A_MERSI_GBAL ...

  5. 高清卫星影像DEM各个遥感卫星数据免费下载,3款软件4个网站推荐给你,从此不再为数据发愁

    在上大学时听老师过一句话"一入遥感深似海,从此数据永相随" 不过不仅遥感处理需要各种数据来练习学习,整个测绘地信行业在工作中也需要各种数据来辅助项目处理.没办法,做数据处理就是要一 ...

  6. 运用卫星数据及AI技术 微软推出新一代模拟飞行游戏

    在E3 2019游戏展上,微软展示了将于2020年推出的新一代<Microsoft Flight Simulator>游戏.借助卫星数据和最新的AI技术,图片看起来非常令人印象深刻. 自2 ...

  7. 使用RSD对高分1号卫星数据进行批量大气校正

    高分数据处理可以有下述5中选项 MSS数据的批量正射校正 MSS数据批量正射校正和大气校正 PAN 数据的批量正射校正 MSS与PAN批量正射校正和融合 MSS与PAN批量正射校正.MSS的大气校正和 ...

  8. 基于 Sentinel-2 卫星数据的像元三分法模型

    Github项目 一.基本概念 端元:组成混合像元的纯净地物被称作是端元: 混合像元产生的原因: 传感器的采样频率小于或等于地表空间变异的频率,使得单个像元对应地面的面积较大, 故包含了多种地物类型: ...

  9. 常用遥感卫星数据汇总

    [日志] 2020/6/18 今天是购物狂欢节,可怜我还在这里写博客,肝作业- 我们这个专业要和卫星大很多交道,所以卫星数据就对我们来说很重要,所以这里来一个小汇总.随着接触到的卫星越来越多,本文会不 ...

  10. 高分1(GF1)、高分2(GF2)卫星数据大气校正

    KEYWORDS:GF1,GF2,RSD,大气校正,遥感软件 0. RSD大气校正 RSD是李国春教授团队开发的一款遥感数处理软件.其大气校正模块是参照USGS LaSRC大气校正流程,使用VC++重 ...

最新文章

  1. Microbiome:扩增子16S分析苏铁类植物微生物组
  2. Elasticsearch 实例管理在京东的使用场景及演进之路
  3. ThinkPHP--栏目增删改查ADSF
  4. 如何计算两个字符串之间的文本相似度?
  5. html标签之常用标签
  6. 百度全面开放搜索流量,进击的智能小程序!
  7. 玩转DataGridView之实现两个GRID间行的拖拽
  8. PMP考试有哪些技巧?(技巧+资料分享)
  9. 泛微oa连接mysql,泛微OA e-cology 数据库接口信息泄露学习
  10. php 获取 客户端,php 获取客户端信息
  11. 常用计算机接口类型,常见的电脑数据接口类型有哪些
  12. python合并excel工作簿_使用python将excel工作簿工作表合并为一个工作表
  13. golang解决数据库中null值的问题
  14. 微信小程序 会议室课堂考勤签到助手 源码
  15. 四、神奇的自然常数e之“自然”初现
  16. python matplotlib绘制等高线、等值线图
  17. Python 中 AttributeError: ‘NoneType‘ object has no attribute ‘X‘ 错误
  18. VINS_FUSION
  19. Proxy用法——让我们创建一个API代理器
  20. 推出免费在线缓存api 大家看有没有用呢

热门文章

  1. Kindle基础使用指南
  2. 再见实体店!推荐一个Python神器,能在线帮助小姐姐试衣服!
  3. 从零开始的Win10系统设置
  4. 计算几何的模板(大神整理)
  5. 在线预览打印Word文档
  6. python3.6实现的A星算法
  7. DiskGenius是一款硬盘分区及数据恢复软件
  8. 基于python的数字印刷体识别_不告诉你我用了它配合Python简简单单开发OCR识别,带你识别手写体、印刷体、身份证等N种,附代码!...
  9. c语言制作电脑病毒原理,用C语言编写的简单病毒
  10. 白话区块链 之 11 - 区块链的链 是什么?