36#define DEBUG_INFO false
37#define DEBUG_ERROR true
38#define grib_debug(format, ...) \
41 fprintf(stderr, format, __VA_ARGS__); \
42 fprintf(stderr, "\n"); \
45#define erreur(format, ...) \
48 fprintf(stderr, "Grib ERROR: "); \
49 fprintf(stderr, format, __VA_ARGS__); \
50 fprintf(stderr, "\n"); \
54#define zuint unsigned int
55#define zuchar unsigned char
57#define GRIB_NOTDEF (-999999999)
63#define GRB_GEOPOT_HGT 7
68#define GRB_DEWPOINT 17
70#define GRB_WIND_DIR 31
71#define GRB_WIND_SPEED 32
76#define GRB_CUR_SPEED 48
80#define GRB_HUMID_SPEC 51
81#define GRB_HUMID_REL 52
82#define GRB_PRECIP_RATE 59
83#define GRB_PRECIP_TOT 61
84#define GRB_SNOW_DEPTH 66
85#define GRB_CLOUD_TOT 71
88#define GRB_COMP_REFL 212
104#define GRB_FRZRAIN_CATEG 141
105#define GRB_SNOW_CATEG 143
110#define GRB_WIND_GUST 180
111#define GRB_WIND_GUST_VX 181
112#define GRB_WIND_GUST_VY 182
117#define GRB_WIND_XY2D 250
118#define GRB_DIFF_TEMPDEW 251
124#define LV_ISOTHERM0 4
125#define LV_ISOBARIC 100
127#define LV_ABOV_MSL 103
128#define LV_ABOV_GND 105
130#define LV_ATMOS_ENT 10
131#define LV_ATMOS_ALL 200
134enum DataCenterModel {
151 static zuint makeCode(zuchar dataType, zuchar levelType, zuint levelValue) {
152 return ((levelValue & 0xFFFF) << 16) + ((levelType & 0xFF) << 8) + dataType;
154 static zuchar getDataType(zuint code) {
return code & 0xFF; }
155 static zuchar getLevelType(zuint code) {
return (code >> 8) & 0xFF; }
156 static zuint getLevelValue(zuint code) {
return (code >> 16) & 0xFFFF; }
277 void multiplyAllData(
double k);
278 void Substract(
const GribRecord &rec,
bool positive =
true);
281 [[nodiscard]]
bool IsOk()
const {
return ok; };
282 [[nodiscard]]
bool IsDataKnown()
const {
return known_data; };
283 [[nodiscard]]
bool IsEof()
const {
return eof; };
284 [[nodiscard]]
bool isDuplicated()
const {
return is_duplicated; };
303 void SetDataType(zuchar t);
394 [[nodiscard]] std::string GetKey()
const {
return data_key; }
395 static std::string MakeKey(
int dataType,
int levelType,
int levelValue);
421 [[nodiscard]]
int GetPeriodP2()
const {
return static_cast<int>(period_p2); }
452 [[nodiscard]]
int GetNi()
const {
return static_cast<int>(Ni); }
458 [[nodiscard]]
int GetNj()
const {
return static_cast<int>(Nj); }
464 [[nodiscard]]
double GetDi()
const {
return Di; }
471 [[nodiscard]]
double GetDj()
const {
return Dj; }
484 [[nodiscard]]
double GetValue(
int i,
int j)
const {
return data[j * Ni + i]; }
486 void SetValue(zuint i, zuint j,
double v) {
487 if (i < Ni && j < Nj) data[j * Ni + i] = v;
504 bool numericalInterpolation =
true,
505 bool dir =
false)
const;
533 bool numericalInterpolation =
true);
544 [[nodiscard]]
inline double GetX(
int i)
const {
return Lo1 + i * Di; }
555 [[nodiscard]]
inline double GetY(
int j)
const {
return La1 + j * Dj; }
566 void getXY(
int i,
int j,
double *x,
double *y)
const {
571 [[nodiscard]]
double GetLatMin()
const {
return lat_min; }
572 [[nodiscard]]
double GetLonMin()
const {
return lon_min; }
573 [[nodiscard]]
double GetLatMax()
const {
return lat_max; }
574 [[nodiscard]]
double GetLonMax()
const {
return lon_max; }
577 [[nodiscard]]
inline bool HasValue(
int i,
int j)
const;
579 [[nodiscard]]
inline bool IsDefined(
int i,
int j)
const {
580 return HasValue(i, j) &&
GetValue(i, j) != GRIB_NOTDEF;
584 [[nodiscard]] time_t GetRecordRefDate()
const {
return ref_date; }
585 [[nodiscard]]
const char *GetStrRecordRefDate()
const {
return str_ref_date; }
588 [[nodiscard]] time_t GetRecordCurrentDate()
const {
return cur_date; }
589 [[nodiscard]]
const char *GetStrRecordCurDate()
const {
return str_cur_date; }
590 void SetRecordCurrentDate(time_t t);
592 [[nodiscard]]
bool IsFilled()
const {
return is_filled; }
593 void SetFilled(
bool val =
true) {
is_filled = val; }
597 [[nodiscard]]
inline bool IsPointInMap(
double x,
double y)
const;
598 [[nodiscard]]
inline bool IsXInMap(
double x)
const;
599 [[nodiscard]]
inline bool IsYInMap(
double y)
const;
603 static bool GetInterpolatedParameters(
const GribRecord &rec1,
605 double &
Lo1,
double &La2,
double &
Lo2,
606 double &Di,
double &Dj,
int &im1,
607 int &jm1,
int &im2,
int &jm2,
int &Ni,
608 int &Nj,
int &rec1offi,
int &rec1offj,
609 int &rec2offi,
int &rec2offj);
653 char str_ref_date[32];
654 char str_cur_date[32];
725 zuint
refyear, refmonth, refday, refhour, refminute;
757 double lat_min, lon_min, lat_max, lon_max;
759 zuchar resol_flags, scan_flags;
761 bool is_earth_spheric;
762 bool is_ueast_vnorth;
763 bool is_scan_i_positive;
764 bool is_scan_j_positive;
773 time_t MakeDate(zuint year, zuint month, zuint day, zuint hour, zuint min,
780inline bool GribRecord::HasValue(
int i,
int j)
const {
787 bit =
static_cast<int>(j * Ni + i);
789 bit =
static_cast<int>(i * Nj + j);
791 zuchar c = bms_bits[bit / 8];
792 zuchar m =
static_cast<zuchar
>(128) >> (bit % 8);
797inline bool GribRecord::IsPointInMap(
double x,
double y)
const {
798 return IsXInMap(x) && IsYInMap(y);
805inline bool GribRecord::IsXInMap(
double x)
const {
812 return x >=
Lo1 && x <= maxLo;
817 return x >=
Lo2 && x <= maxLo;
821inline bool GribRecord::IsYInMap(
double y)
const {
823 return y <= La1 && y >= La2;
825 return y >= La1 && y <= La2;
A meteorological data grid from a GRIB (Gridded Binary) file.
int GetNj() const
Returns the number of points in the latitude (j) direction of the grid.
static bool GetInterpolatedValues(double &M, double &A, const GribRecord *GRX, const GribRecord *GRY, double px, double py, bool numericalInterpolation=true)
Gets spatially interpolated wind or current vector values at a specific latitude/longitude point.
bool eof
Signals when the end of the GRIB file has been reached during parsing.
zuint periodsec
Forecast period in seconds.
static void Polar2UV(GribRecord *pDIR, GribRecord *pSPEED)
Converts wind or current values from polar (direction/speed) to cartesian (U/V) components.
time_t cur_date
Unix timestamp of when this forecast is valid.
bool is_duplicated
Indicates if this record was created through copying rather than direct reading.
zuchar GetTimeRange() const
Returns the time range indicator that defines how P1 and P2 should be interpreted.
zuint GetDataCenterModel() const
Returns the numerical weather prediction model/center that produced this data.
void getXY(int i, int j, double *x, double *y) const
Converts grid indices to longitude/latitude coordinates.
double Lo2
Grid end coordinates.
zuint period_p1
Time range indicators for this forecast step.
double GetY(int j) const
Converts grid index j to latitude in degrees.
double Lo1
Grid origin coordinates.
bool is_filled
Indicates whether the data array has been populated.
zuchar GetIdModel() const
Returns the model/process ID within the originating center.
static GribRecord * Interpolated2DRecord(GribRecord *&rety, const GribRecord &rec1x, const GribRecord &rec1y, const GribRecord &rec2x, const GribRecord &rec2y, double d)
Creates temporally interpolated records for vector fields (wind, currents).
int GetPeriodP2() const
Returns the end of the period (P2) used for this record.
zuchar id_model
Model identifier within the originating center.
zuchar GetDataType() const
Returns the type of meteorological parameter stored in this grid.
double GetValue(int i, int j) const
Returns the data value at a specific grid point.
double GetX(int i) const
Converts grid index i to longitude in degrees.
std::string data_key
Unique string identifier constructed from data type, level type, and level value.
zuint GetPeriodSec() const
Returns the forecast period in seconds from reference time.
static GribRecord * InterpolatedRecord(const GribRecord &rec1, const GribRecord &rec2, double d, bool dir=false)
Creates a new GribRecord by temporally interpolating between two time points.
zuchar id_grid
Grid identifier used by the originating center.
bool ok
Indicates record validity.
double GetInterpolatedValue(double px, double py, bool numericalInterpolation=true, bool dir=false) const
Get spatially interpolated value at exact lat/lon position.
zuchar GetIdCenter() const
Returns the originating center ID as defined by WMO (World Meteorological Organization).
int id
Unique identifier for this record.
bool hasBMS
Indicates presence of a bitmap section.
zuint level_value
Numeric value associated with level_type.
int GetPeriodP1() const
Returns the start of the period (P1) used for this record.
bool wave_data
Differentiates wave-related parameters (height, direction, period) from other meteorological data for...
int GetNi() const
Returns the number of points in the longitude (i) direction of the grid.
zuint GetLevelValue() const
Returns the numeric value associated with the level type.
zuint refyear
Components of the reference time for this forecast.
zuchar data_type
Parameter identifier as defined by GRIB tables.
double GetDj() const
Returns the grid spacing in latitude (j) direction in degrees.
time_t ref_date
Unix timestamp of model initialization time.
zuchar level_type
Vertical level type indicator.
bool known_data
Indicates whether the data type in this record is recognized by the parser.
int data_center_model
Identifies the numerical weather model that produced this data.
zuchar id_center
Originating center ID as defined by WMO common table C-1.
zuchar edition_number
GRIB edition number, indicating the version of the GRIB specification used.
double GetDi() const
Returns the grid spacing in longitude (i) direction in degrees.
zuchar GetIdGrid() const
Returns the grid definition template number.
zuchar time_range
Statistical processing indicator.
zuchar GetLevelType() const
Returns the type of vertical level for this grid's data.