📄 earthprobedata.c
字号:
/*------------------------------------------------------------------------------*
* File Name: EarthProbeData.c *
* Creation: July 1, 2002 *
* Purpose: Import EarthProbe files into a matrix *
* Copyright (c) OriginLab Corp. 2002 *
* *
* Modification Log: *
*------------------------------------------------------------------------------*/
////////////////////////////////////////////////////////////////////////////////////
// you can include just this typical header file for most Origin built-in functions and classes
// and it takes a reasonable amount of time to compile,
#include <origin.h>
#include <Tree.h>
#include "Filter_Utils.h"
////////////////////////////////////////////////////////////////////////////////////
#define EP_HDR_LINE_LEN 80
#define EP_HDR_LINE_COUNT 3
// The data is stored in the files as a string of numbers.
// Each value is always 3 characters long.
// Example: 123456789234 equals four values 123, 456, 789. and 234
#define EP_DATA_ELEMENT_STR_LEN 3
typedef struct {
int iDayOfYear;
int iMonth;
int iDayOfMonth;
int iYear;
int iHour;
int iMin;
char szText[80];
int iLongitudeBinCount;
double dLongitudeStart;
double dLongitudeStep;
int iLatitudeBinCount;
double dLatitudeStart;
double dLatitudeStep;
} EPHEADER;
enum {
EPR_SUCCESS = 0,
EPR_ERR_FILE_OPEN,
EPR_ERR_HEADER,
EPR_ERR_READ_DATA,
EPR_ERR_NO_FILE_SPECIFIED,
EPR_ERR_TARGET_MATRIX_NOT_VALID,
EPR_ERR_UNKNOWN_FILE_EXT,
EPR_ERR_PARSE_DATA,
};
enum { // EarthProbe file type IDs
EP_TYPE_UNKNOWN = 0,
EP_TYPE_AEROSOL,
EP_TYPE_OZONE,
EP_TYPE_REFLECTIVE,
EP_TYPE_UV,
};
////////////////////////////////////////////////////////////////////////////////////
// start your functions here
//--------------------------------------------------------------------------
// EarthProbe_FileExtToType
//
// This function returns an integer that represents the type of the
// EarthProbe file based on the file's extension.
//
// return
// EP_TYPE_* code
//--------------------------------------------------------------------------
int EarthProbe_FileExtToType(LPCSTR lpcstr)
{
string strFileExt(lpcstr);
if( 0 == strFileExt.CompareNoCase("epa") )
return EP_TYPE_AEROSOL;
if( 0 == strFileExt.CompareNoCase("epe") )
return EP_TYPE_UV;
if( 0 == strFileExt.CompareNoCase("epr") )
return EP_TYPE_REFLECTIVE;
if( 0 == strFileExt.CompareNoCase("ept") )
return EP_TYPE_OZONE;
return EP_TYPE_UNKNOWN;
}
//--------------------------------------------------------------------------
// monthtoi
//
// Return the index of the named month. The comparison is case insensative.
// Example: Passing "January" or "JAN" will return 0.
//
// return:
// index of named month or -1 if not a month name.
//--------------------------------------------------------------------------
int monthtoi(LPCSTR lpcstrMonth)
{
/* string strMonths[] = {
"january",
"february",
"march",
"april",
"may",
"june",
"july",
"august",
"september",
"october",
"november",
"december"
};
*/
string strMonths[12];
strMonths[0] = "january";
strMonths[1] = "february";
strMonths[2] = "march";
strMonths[3] = "april";
strMonths[4] = "may";
strMonths[5] = "june";
strMonths[6] = "july";
strMonths[7] = "august";
strMonths[8] = "september";
strMonths[9] = "october";
strMonths[10] = "november";
strMonths[11] = "december";
string strMonth(lpcstrMonth);
strMonth.MakeLower();
for( int i = 0; i < 12; i++ )
{
if( strMonths[i].Find(strMonth) != -1 )
return i;
}
return -1;
}
//--------------------------------------------------------------------------
// EarthProbe_ReadHeader
//
// This function reads the 3 lines of header, extracts the header info,
// and puts the header info into a structure.
//
// return:
// EPR_SUCCESS or an EPR_ERR_* code
//--------------------------------------------------------------------------
int EarthProbe_ReadHeader(stdioFile &fil, EPHEADER &eph)
{
string strLine;
// Read first header line.
if( FALSE == fil.ReadString(strLine) || EP_HDR_LINE_LEN != strLine.GetLength() )
return EPR_ERR_HEADER;
eph.iDayOfYear = atoi(strLine.Mid(6, 3));
eph.iMonth = monthtoi(strLine.Mid(10, 3));
eph.iDayOfMonth = atoi(strLine.Mid(14, 2));
eph.iYear = atoi(strLine.Mid(18, 4));
lstrcpy(eph.szText, strLine.Mid(26, 24));
eph.iHour = atoi(strLine.Mid(71, 2));
eph.iMin = atoi(strLine.Mid(74, 2));
if( 'A' == strLine[77] )
eph.iHour += 12;
// Read second header line.
if( FALSE == fil.ReadString(strLine) || EP_HDR_LINE_LEN != strLine.GetLength() )
return EPR_ERR_HEADER;
eph.iLongitudeBinCount = atoi(strLine.Mid(14, 3));
eph.dLongitudeStart = atof(strLine.Mid(35, 7));
eph.dLongitudeStep = atof(strLine.Mid(60, 4));
// Read third header line.
if( FALSE == fil.ReadString(strLine) || EP_HDR_LINE_LEN != strLine.GetLength() )
return EPR_ERR_HEADER;
eph.iLatitudeBinCount = atoi(strLine.Mid(14, 3));
eph.dLatitudeStart = atof(strLine.Mid(35, 7));
eph.dLatitudeStep = atof(strLine.Mid(60, 4));
return EPR_SUCCESS;
}
//--------------------------------------------------------------------------
// EarthProbe_ParseStrData
//
// The data is stored in the files as a string of numbers.
// Each value is always 3 characters long.
// Example: 123456789234 equals four values 123, 456, 789. and 234
// This function will take a string of numbers, parse the values, and puts
// the values into a vector.
//
// return:
// The number of values parsed.
// zero for failure.
//--------------------------------------------------------------------------
int EarthProbe_ParseStrData(vector<int> &v, LPCTSTR lpcstrData)
{
string strData(lpcstrData);
int i = strData.GetLength();
if( (i % EP_DATA_ELEMENT_STR_LEN) )
return 0; // invalid str length
int iCount = i / EP_DATA_ELEMENT_STR_LEN;
v.SetSize(iCount);
string strDataElement;
for( i = 0; i < iCount; i++ )
{
strDataElement = strData.Mid(i * EP_DATA_ELEMENT_STR_LEN, EP_DATA_ELEMENT_STR_LEN);
v[i] = atoi(strDataElement);
}
return iCount;
}
//--------------------------------------------------------------------------
// EarthProbe_ReadLongitudeBins
//
// This function will read one row of data for the next latitude.
//
// return:
// EPR_SUCCESS or an EPR_ERR_* code
//--------------------------------------------------------------------------
int EarthProbe_ReadLongitudeBins(stdioFile &fil, vector<int> &v)
{
BOOL bDone = FALSE;
int iRet, iVecIdx = 0;
vector<int> vTmp;
string str;
v.SetSize(0);
while( !bDone )
{
if( FALSE == fil.ReadString(str) )
return EPR_ERR_READ_DATA;
str.Delete(0); // first char is always a space and not needed
// The last line of data for any given latitude will contain "lat="
// at the end of the line. For the line that has this we need to scan
// back from the "lat" to the first non-space char.
int i = str.Find("lat");
if( i != -1 ) // if found "lat"
{
bDone = TRUE;
do
{
i--;
} while( i && str[i] == ' ' );
// currently we do nothing with the "lat" value.
str = str.Left(i + 1);
}
if( 0 == EarthProbe_ParseStrData(vTmp, str) )
return EPR_ERR_PARSE_DATA;
// Append temp vector to target vector.
v.Append(vTmp);
}
return EPR_SUCCESS;
}
//--------------------------------------------------------------------------
// EarthProbe_FileToMatrix
//
// Load an EarthProbe data file into a matrix.
//
// return:
// EPR_SUCCESS or an EPR_ERR_* code
//--------------------------------------------------------------------------
int EarthProbe_FileToMatrix(matrix &matEarthProbe, LPCSTR strFile)
{
string strFileExt(strFile);
int iType = EarthProbe_FileExtToType(strFileExt.Right(3));
if( EP_TYPE_UNKNOWN == iType )
return EPR_ERR_UNKNOWN_FILE_EXT;
stdioFile fil;
if( fil.Open(strFile, file::modeRead | file::shareDenyWrite) == FALSE )
return EPR_ERR_FILE_OPEN;
EPHEADER eph;
int iRet = EarthProbe_ReadHeader(fil, eph);
if( EPR_SUCCESS == iRet )
{
matEarthProbe.SetSize(eph.iLatitudeBinCount, eph.iLongitudeBinCount);
vector<int> v;
for( int i = 0; i < eph.iLatitudeBinCount; i++ )
{
// Read logitude bins into vector.
v.SetSize(eph.iLongitudeBinCount);
iRet = EarthProbe_ReadLongitudeBins(fil, v);
if( EPR_SUCCESS != iRet )
break;
// Copy vector to matrix row.
matEarthProbe.SetRow(v, i);
}
}
// We do not need the file anymore.
fil.Close();
// Depending on the file type we need to do some conversions to
// get the actual data values.
switch( iType )
{
case EP_TYPE_AEROSOL: // *.EPA
// Aerosol data needs to be divided by 10.
// " 1" == 0.1
// " 11" == 1.1
// "111" == 11.1
// "999" == missing value
matEarthProbe /= 10;
// Replace all 99.9 values with missing value.
matEarthProbe.Replace(99.9, NANUM, 2);
break;
case EP_TYPE_REFLECTIVE: // *.EPR
// Reflectivity data is integer data.
// " 83" == 83%
// "999" == fill value
// Replace all 999 values with missing value.
matEarthProbe.Replace(999, NANUM, 2);
break;
case EP_TYPE_OZONE: // *.EPT
// Ozone data is integer data.
// "234" == 234 du
// " 0" == fill value
// Replace all 0 values with missing value.
matEarthProbe.Replace(0, NANUM, 2);
break;
case EP_TYPE_UV: // *.EPE
// UV Erythemal Irradiance.
// "342" == 4.2*10^3
// "999" == fill value
// Set all cells with a value of 999 to missing value.
matEarthProbe.Replace(999, NANUM, 2);
int iPow;
double d;
for( int iCol = 0; iCol < matEarthProbe.GetNumCols(); iCol++ )
{
for( int iRow = 0; iRow < matEarthProbe.GetNumRows(); iRow++ )
{
if( matEarthProbe[iCol][iRow] != NANUM )
{
iPow = matEarthProbe[iCol][iRow] / 100;
d = (matEarthProbe[iCol][iRow] - (iPow * 100)) / 10;
matEarthProbe[iCol][iRow] = d * 10 ^ iPow;
}
}
}
break;
}
return iRet;
}
//--------------------------------------------------------------------------
// ImportEarthProbe
//
// Import the specified EarthProbe data file into the specified matrix.
//
// Return:
// zero for success
// non-zero for error
//--------------------------------------------------------------------------
int ImportEarthProbe(Page &pgTarget, TreeNode &trFilter, LPCSTR lpcszFile, int nFile)
{
if( trFilter.Type.nVal != FILTER_TYPE_USERDEFINED )
return 1;
if( EXIST_MATRIX != pgTarget.GetType() )
return 1;
Matrix mat(pgTarget.GetName());
if( !mat.IsValid() )
return 1;
return EarthProbe_FileToMatrix(mat, lpcszFile);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -