OpenCPN Partial API docs
Loading...
Searching...
No Matches
GribRecord.h
Go to the documentation of this file.
1/**********************************************************************
2zyGrib: meteorological GRIB file viewer
3Copyright (C) 2008 - Jacques Zaninetti - http://www.zygrib.org
4
5This program is free software: you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation, either version 3 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program. If not, see <http://www.gnu.org/licenses/>.
17***********************************************************************/
27#ifndef GRIBRECORD_H
28#define GRIBRECORD_H
29
30#include <iostream>
31#include <cmath>
32
33#define DEBUG_INFO false
34#define DEBUG_ERROR true
35#define grib_debug(format, ...) \
36 { \
37 if (DEBUG_INFO) { \
38 fprintf(stderr, format, __VA_ARGS__); \
39 fprintf(stderr, "\n"); \
40 } \
41 }
42#define erreur(format, ...) \
43 { \
44 if (DEBUG_ERROR) { \
45 fprintf(stderr, "Grib ERROR: "); \
46 fprintf(stderr, format, __VA_ARGS__); \
47 fprintf(stderr, "\n"); \
48 } \
49 }
50
51#define zuint unsigned int
52#define zuchar unsigned char
53
54#define GRIB_NOTDEF -999999999
55
56//--------------------------------------------------------
57// dataTypes Cf function translateDataType()
58//--------------------------------------------------------
59#define GRB_PRESSURE 2 /* Pa */
60#define GRB_GEOPOT_HGT 7 /* gpm */
61#define GRB_TEMP 11 /* K */
62#define GRB_TPOT 13 /* K */
63#define GRB_TMAX 15 /* K */
64#define GRB_TMIN 16 /* K */
65#define GRB_DEWPOINT 17 /* K */
66
67#define GRB_WIND_DIR 31 /* Deg. Wind Direction */
68#define GRB_WIND_SPEED 32 /* m/s Wind Speed */
69#define GRB_WIND_VX 33 /* m/s U */
70#define GRB_WIND_VY 34 /* m/s V */
71
72#define GRB_CUR_DIR 47 /* Deg. Direction of current */
73#define GRB_CUR_SPEED 48 /* m/s Speed of current */
74#define GRB_UOGRD 49 /*"u-component of current", "m/s" */
75#define GRB_VOGRD 50 /*"v-component of current", "m/s" */
76
77#define GRB_HUMID_SPEC 51 /* kg/kg */
78#define GRB_HUMID_REL 52 /* % */
79#define GRB_PRECIP_RATE 59 /* l/m2/s */
80#define GRB_PRECIP_TOT 61 /* l/m2 */
81#define GRB_SNOW_DEPTH 66 /* m */
82#define GRB_CLOUD_TOT 71 /* % */
83#define GRB_HTSGW 100 /* m */
84#define GRB_WTMP 80 /* "Water Temperature", "K" */
85#define GRB_COMP_REFL 212 /* dBZ */
86
87#define GRB_WVDIR 101
88#define GRB_WVHGT 102
89#define GRB_WVPER 103
90#define GRB_SWDIR 104
91#define GRB_SWELL 105
92#define GRB_SWPER 106
93#define GRB_DIRPW 107
94#define GRB_PERPW 108
95#define GRB_DIRSW 109
96#define GRB_PERSW 110
97#define GRB_PER 209
98#define GRB_DIR 210
99
100#define GRB_CRAIN 140 /* "Categorical rain", "yes=1;no=0" */
101#define GRB_FRZRAIN_CATEG 141 /* 1=yes 0=no */
102#define GRB_SNOW_CATEG 143 /* 1=yes 0=no */
103#define GRB_CAPE 157 /* J/kg */
104
105#define GRB_TSEC \
106 171 /* "Seconds prior to initial reference time (defined in bytes 18-20)" */
107#define GRB_WIND_GUST 180 /* m/s "wind gust */
108#define GRB_WIND_GUST_VX 181 /* m/s */
109#define GRB_WIND_GUST_VY 182 /* m/s */
110
111#define GRB_USCT 190 /* Scatterometer estimated U Wind, NCEP Center 7 */
112#define GRB_VSCT 191 /* Scatterometer estimated V Wind, NCEP Center 7 */
113
114#define GRB_WIND_XY2D 250 /* private : GRB_WIND_VX+GRB_WIND_VX */
115#define GRB_DIFF_TEMPDEW 251 /* private : GRB_TEMP-GRB_DEWPOINT */
116
117//--------------------------------------------------------
118// Levels types (altitude reference)
119//--------------------------------------------------------
120#define LV_GND_SURF 1
121#define LV_ISOTHERM0 4
122#define LV_ISOBARIC 100
123#define LV_MSL 102
124#define LV_ABOV_MSL 103
125#define LV_ABOV_GND 105
126#define LV_SIGMA 107
127#define LV_ATMOS_ENT 10
128#define LV_ATMOS_ALL 200
129//---------------------------------------------------------
130enum DataCenterModel {
131 NOAA_GFS,
132 NOAA_NCEP_WW3,
133 NOAA_NCEP_SST,
134 NOAA_RTOFS,
135 FNMOC_WW3_GLB,
136 FNMOC_WW3_MED,
137 NORWAY_METNO,
138 ECMWF_ERA5,
139 KNMI_HIRLAM,
140 KNMI_HARMONIE_AROME,
141 OTHER_DATA_CENTER
142};
143
144//----------------------------------------------
145class GribCode {
146public:
147 static zuint makeCode(zuchar dataType, zuchar levelType, zuint levelValue) {
148 return ((levelValue & 0xFFFF) << 16) + ((levelType & 0xFF) << 8) + dataType;
149 }
150 static zuchar getDataType(zuint code) { return code & 0xFF; }
151 static zuchar getLevelType(zuint code) { return (code >> 8) & 0xFF; }
152 static zuint getLevelValue(zuint code) { return (code >> 16) & 0xFFFF; }
153};
154
183public:
185 GribRecord(const GribRecord &rec);
186 GribRecord() { m_bfilled = false; }
187
188 virtual ~GribRecord();
189
221 static GribRecord *InterpolatedRecord(const GribRecord &rec1,
222 const GribRecord &rec2, double d,
223 bool dir = false);
250 const GribRecord &rec1x,
251 const GribRecord &rec1y,
252 const GribRecord &rec2x,
253 const GribRecord &rec2y, double d);
254
255 static GribRecord *MagnitudeRecord(const GribRecord &rec1,
256 const GribRecord &rec2);
257
271 static void Polar2UV(GribRecord *pDIR, GribRecord *pSPEED);
272
273 void multiplyAllData(double k);
274 void Substract(const GribRecord &rec, bool positive = true);
275 void Average(const GribRecord &rec);
276
277 bool isOk() const { return ok; };
278 bool isDataKnown() const { return knownData; };
279 bool isEof() const { return eof; };
280 bool isDuplicated() const { return IsDuplicated; };
298 zuchar getDataType() const { return dataType; }
299 void setDataType(const zuchar t);
300
315 zuchar getLevelType() const { return levelType; }
328 zuint getLevelValue() const { return levelValue; }
348 zuint getDataCenterModel() const { return dataCenterModel; }
349 //-----------------------------------------
350
364 zuchar getIdCenter() const { return idCenter; }
376 zuchar getIdModel() const { return idModel; }
387 zuchar getIdGrid() const { return idGrid; }
388
389 //-----------------------------------------
390 std::string getKey() const { return dataKey; }
391 static std::string makeKey(int dataType, int levelType, int levelValue);
392
393 //-----------------------------------------
405 int getPeriodP1() const { return periodP1; }
417 int getPeriodP2() const { return periodP2; }
427 zuint getPeriodSec() const { return periodsec; }
440 zuchar getTimeRange() const { return timeRange; }
441
442 // Number of points in the grid
448 int getNi() const { return Ni; }
454 int getNj() const { return Nj; }
460 double getDi() const { return Di; }
467 double getDj() const { return Dj; }
468
480 double getValue(int i, int j) const { return data[j * Ni + i]; }
481
482 void setValue(zuint i, zuint j, double v) {
483 if (i < Ni && j < Nj) data[j * Ni + i] = v;
484 }
485
499 double getInterpolatedValue(double px, double py,
500 bool numericalInterpolation = true,
501 bool dir = false) const;
502
527 static bool getInterpolatedValues(double &M, double &A, const GribRecord *GRX,
528 const GribRecord *GRY, double px, double py,
529 bool numericalInterpolation = true);
530
540 inline double getX(int i) const { return Lo1 + i * Di; }
551 inline double getY(int j) const { return La1 + j * Dj; }
562 void getXY(int i, int j, double *x, double *y) const {
563 *x = getX(i);
564 *y = getY(j);
565 };
566
567 double getLatMin() const { return latMin; }
568 double getLonMin() const { return lonMin; }
569 double getLatMax() const { return latMax; }
570 double getLonMax() const { return lonMax; }
571
572 // Is there a value at a particular grid point ?
573 inline bool hasValue(int i, int j) const;
574 // Is there a value that is not GRIB_NOTDEF ?
575 inline bool isDefined(int i, int j) const {
576 return hasValue(i, j) && getValue(i, j) != GRIB_NOTDEF;
577 }
578
579 // Reference date Date (file creation date)
580 time_t getRecordRefDate() const { return refDate; }
581 const char *getStrRecordRefDate() const { return strRefDate; }
582
583 // Date courante des prévisions
584 time_t getRecordCurrentDate() const { return curDate; }
585 const char *getStrRecordCurDate() const { return strCurDate; }
586 void setRecordCurrentDate(time_t t);
587 void print();
588 bool isFilled() { return m_bfilled; }
589 void setFilled(bool val = true) { m_bfilled = val; }
590
591private:
592 // Is a point within the extent of the grid?
593 inline bool isPointInMap(double x, double y) const;
594 inline bool isXInMap(double x) const;
595 inline bool isYInMap(double y) const;
596
597protected:
598 // private:
599 static bool GetInterpolatedParameters(const GribRecord &rec1,
600 const GribRecord &rec2, double &La1,
601 double &Lo1, double &La2, double &Lo2,
602 double &Di, double &Dj, int &im1,
603 int &jm1, int &im2, int &jm2, int &Ni,
604 int &Nj, int &rec1offi, int &rec1offj,
605 int &rec2offi, int &rec2offj);
606
613 int id;
621 bool ok;
643 bool eof;
648 std::string dataKey;
649 char strRefDate[32];
650 char strCurDate[32];
669
670 //---------------------------------------------
671 // SECTION 0: THE INDICATOR SECTION (IS)
672 //---------------------------------------------
678
679 // SECTION 1: THE PRODUCT DEFINITION SECTION (PDS)
684 zuchar idCenter;
689 zuchar idModel;
694 zuchar idGrid;
699 zuchar dataType; // octet 9 = parameters and units
705 zuchar levelType;
711
716 bool hasBMS;
721 zuint refyear, refmonth, refday, refhour, refminute;
722 // zuchar periodP1, periodP2;
727 zuint periodP1, periodP2;
733 zuchar timeRange;
742 time_t refDate;
746 time_t curDate;
747 // SECTION 2: THE GRID DESCRIPTION SECTION (GDS)
748 zuchar NV, PV;
749 zuchar gridType;
750 zuint Ni, Nj;
751 double La1, Lo1;
752 double La2, Lo2;
753 double latMin, lonMin, latMax, lonMax;
754 double Di, Dj;
755 zuchar resolFlags, scanFlags;
756 bool hasDiDj;
757 bool isEarthSpheric;
758 bool isUeastVnorth;
759 bool isScanIpositive;
760 bool isScanJpositive;
761 bool isAdjacentI;
762 // SECTION 3: BIT MAP SECTION (BMS)
763 zuint BMSsize;
764 zuchar *BMSbits;
765 // SECTION 4: BINARY DATA SECTION (BDS)
766 double *data;
767 // SECTION 5: END SECTION (ES)
768
769 time_t makeDate(zuint year, zuint month, zuint day, zuint hour, zuint min,
770 zuint sec);
771
772 // void print();
773};
774
775//==========================================================================
776inline bool GribRecord::hasValue(int i, int j) const {
777 // is data present in BMS ?
778 if (!hasBMS) {
779 return true;
780 }
781 int bit;
782 if (isAdjacentI) {
783 bit = j * Ni + i;
784 } else {
785 bit = i * Nj + j;
786 }
787 zuchar c = BMSbits[bit / 8];
788 zuchar m = (zuchar)128 >> (bit % 8);
789 return (m & c) != 0;
790}
791
792//-----------------------------------------------------------------
793inline bool GribRecord::isPointInMap(double x, double y) const {
794 return isXInMap(x) && isYInMap(y);
795 /* if (Dj < 0)
796 return x>=Lo1 && y<=La1 && x<=Lo1+(Ni-1)*Di && y>=La1+(Nj-1)*Dj;
797 else
798 return x>=Lo1 && y>=La1 && x<=Lo1+(Ni-1)*Di && y<=La1+(Nj-1)*Dj;*/
799}
800//-----------------------------------------------------------------
801inline bool GribRecord::isXInMap(double x) const {
802 // return x>=Lo1 && x<=Lo1+(Ni-1)*Di;
803 // printf ("%f %f %f\n", Lo1, Lo2, x);
804 if (Di > 0) {
805 double maxLo = Lo2;
806 if (Lo2 + Di >= 360) /* grib that covers the whole world */
807 maxLo += Di;
808 return x >= Lo1 && x <= maxLo;
809 } else {
810 double maxLo = Lo1;
811 if (Lo2 + Di >= 360) /* grib that covers the whole world */
812 maxLo += Di;
813 return x >= Lo2 && x <= maxLo;
814 }
815}
816//-----------------------------------------------------------------
817inline bool GribRecord::isYInMap(double y) const {
818 if (Dj < 0)
819 return y <= La1 && y >= La2;
820 else
821 return y >= La1 && y <= La2;
822}
823
824#endif
Represents a meteorological data grid from a GRIB (Gridded Binary) file.
Definition GribRecord.h:182
zuchar getTimeRange() const
Returns the time range indicator that defines how P1 and P2 should be interpreted.
Definition GribRecord.h:440
bool eof
Signals when the end of the GRIB file has been reached during parsing.
Definition GribRecord.h:643
zuint periodsec
Forecast period in seconds.
Definition GribRecord.h:738
static void Polar2UV(GribRecord *pDIR, GribRecord *pSPEED)
Converts wind or current values from polar (direction/speed) to cartesian (U/V) components.
int getPeriodP1() const
Returns the start of the period (P1) used for this record.
Definition GribRecord.h:405
zuchar dataType
Parameter identifier as defined by GRIB tables.
Definition GribRecord.h:699
double getDi() const
Returns the grid spacing in longitude (i) direction in degrees.
Definition GribRecord.h:460
zuchar editionNumber
GRIB edition number, indicating the version of the GRIB specification used.
Definition GribRecord.h:677
bool knownData
Indicates whether the data type in this record is recognized by the parser.
Definition GribRecord.h:626
zuchar levelType
Vertical level type indicator.
Definition GribRecord.h:705
void getXY(int i, int j, double *x, double *y) const
Converts grid indices to longitude/latitude coordinates.
Definition GribRecord.h:562
double Lo2
Grid end coordinates.
Definition GribRecord.h:752
double getDj() const
Returns the grid spacing in latitude (j) direction in degrees.
Definition GribRecord.h:467
zuchar getIdModel() const
Returns the model/process ID within the originating center.
Definition GribRecord.h:376
double Lo1
Grid origin coordinates.
Definition GribRecord.h:751
zuint getPeriodSec() const
Returns the forecast period in seconds from reference time.
Definition GribRecord.h:427
time_t curDate
Unix timestamp of when this forecast is valid.
Definition GribRecord.h:746
int getPeriodP2() const
Returns the end of the period (P2) used for this record.
Definition GribRecord.h:417
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).
bool waveData
Differentiates wave-related parameters (height, direction, period) from other meteorological data for...
Definition GribRecord.h:631
zuchar timeRange
Statistical processing indicator.
Definition GribRecord.h:733
zuint getDataCenterModel() const
Returns the numerical weather prediction model/center that produced this data.
Definition GribRecord.h:348
double getInterpolatedValue(double px, double py, bool numericalInterpolation=true, bool dir=false) const
Get spatially interpolated value at exact lat/lon position.
bool IsDuplicated
Indicates if this record was created through copying rather than direct reading.
Definition GribRecord.h:639
zuchar idCenter
Originating center ID as defined by WMO common table C-1.
Definition GribRecord.h:684
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.
bool ok
Indicates record validity.
Definition GribRecord.h:621
int getNi() const
Returns the number of points in the longitude (i) direction of the grid.
Definition GribRecord.h:448
zuchar idGrid
Grid identifier used by the originating center.
Definition GribRecord.h:694
zuint periodP1
Time range indicators for this forecast step.
Definition GribRecord.h:727
double getX(int i) const
Converts grid index i to longitude in degrees.
Definition GribRecord.h:540
int getNj() const
Returns the number of points in the latitude (j) direction of the grid.
Definition GribRecord.h:454
time_t refDate
Unix timestamp of model initialization time.
Definition GribRecord.h:742
int id
Unique identifier for this record.
Definition GribRecord.h:613
bool hasBMS
Indicates presence of a bitmap section.
Definition GribRecord.h:716
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.
int dataCenterModel
Identifies the numerical weather model that produced this data.
Definition GribRecord.h:663
double getY(int j) const
Converts grid index j to latitude in degrees.
Definition GribRecord.h:551
zuchar getIdGrid() const
Returns the grid definition template number.
Definition GribRecord.h:387
double getValue(int i, int j) const
Returns the data value at a specific grid point.
Definition GribRecord.h:480
bool m_bfilled
Indicates whether the data array has been populated.
Definition GribRecord.h:668
zuint refyear
Components of the reference time for this forecast.
Definition GribRecord.h:721
zuint levelValue
Numeric value associated with levelType.
Definition GribRecord.h:710
zuint getLevelValue() const
Returns the numeric value associated with the level type.
Definition GribRecord.h:328
zuchar getLevelType() const
Returns the type of vertical level for this grid's data.
Definition GribRecord.h:315
zuchar idModel
Model identifier within the originating center.
Definition GribRecord.h:689
zuchar getDataType() const
Returns the type of meteorological parameter stored in this grid.
Definition GribRecord.h:298
zuchar getIdCenter() const
Returns the originating center ID as defined by WMO (World Meteorological Organization).
Definition GribRecord.h:364
std::string dataKey
Unique string identifier constructed from data type, level type, and level value.
Definition GribRecord.h:648