Skip to content

Commit 1064cad

Browse files
Multi-layer grib.
Add code ccomments.
1 parent 5c51c25 commit 1064cad

File tree

7 files changed

+277
-52
lines changed

7 files changed

+277
-52
lines changed

plugins/grib_pi/src/GribReader.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,18 @@ void GribReader::clean_all_vectors() {
6060
delete ls;
6161
}
6262
mapGribRecords.clear();
63+
deletedRecords.clear();
6364
}
6465
//-------------------------------------------------------------------------------
6566
void GribReader::clean_vector(std::vector<GribRecord *> &ls) {
6667
std::vector<GribRecord *>::iterator it;
6768
for (it = ls.begin(); it != ls.end(); it++) {
68-
delete *it;
69-
*it = NULL;
69+
GribRecord *ptr = *it;
70+
wxLogMessage("clean_vector. About to delete ptr: %p. Already deleted: %d", ptr, deletedRecords.find(ptr) != deletedRecords.end());
71+
if(ptr && deletedRecords.find(ptr) == deletedRecords.end()) {
72+
delete ptr;
73+
deletedRecords.insert(ptr);
74+
}
7075
}
7176
ls.clear();
7277
}
@@ -82,6 +87,7 @@ void GribReader::storeRecordInMap(GribRecord *rec) {
8287
#endif
8388
std::map<std::string, std::vector<GribRecord *> *>::iterator it;
8489
it = mapGribRecords.find(rec->getKey());
90+
wxLogMessage("storeRecordInMap: %p. Key: %s", rec, rec->getKey());
8591
if (it == mapGribRecords.end()) {
8692
mapGribRecords[rec->getKey()] = new std::vector<GribRecord *>;
8793
assert(mapGribRecords[rec->getKey()]);
@@ -131,24 +137,29 @@ void GribReader::readAllGribRecords() {
131137

132138
if (is_v2 == false) {
133139
rec = new GribV1Record(file, id);
140+
wxLogMessage("readAllGribRecords. Create GribV1Record: %p", rec);
134141
if (rec->isOk() == false) {
135142
delete rec;
136143
rec = new GribV2Record(file, id);
144+
wxLogMessage("readAllGribRecords. GribV1Record not ok, deleted. Create GribV2Record: %p. isOk: %d", rec, rec->isOk());
137145
is_v2 = rec->isOk();
138146
}
139147
} else {
140148
GribV2Record *rec2 = dynamic_cast<GribV2Record *>(rec);
141149
if (rec2 && rec2->hasMoreDataSet()) {
142150
rec = rec2->GribV2NextDataSet(file, id);
151+
wxLogMessage("rec2 hasMoreDataSet. Create GribV2Record: %p from rec2: %p", rec, rec2);
143152
delete prevDataSet;
144153
} else {
145154
rec = new GribV2Record(file, id);
155+
wxLogMessage("rec2 has no more DataSet. Create GribV2Record: %p", rec);
146156
}
147157

148158
is_v2 = rec->isOk();
149159
if (rec->isOk() == false) {
150160
delete rec;
151161
rec = new GribV1Record(file, id);
162+
wxLogMessage("rec2 is not ok. Create GribV1Record: %p", rec);
152163
}
153164
}
154165
prevDataSet = 0;
@@ -290,6 +301,7 @@ void GribReader::copyFirstCumulativeRecord(int dataType, int levelType,
290301
rec = getFirstGribRecord(dataType, levelType, levelValue);
291302
if (rec != NULL) {
292303
GribRecord *r2 = new GribRecord(*rec);
304+
wxLogMessage("copyFirstCumulativeRecord. Create GribRecord: %p", r2);
293305
r2->setRecordCurrentDate(dateref); // 1er enregistrement factice
294306
storeRecordInMap(r2);
295307
}
@@ -334,6 +346,7 @@ void GribReader::copyMissingWaveRecords(int dataType, int levelType,
334346
if (rec2 && rec2->isOk()) {
335347
// create a copied record from date2
336348
GribRecord *r2 = new GribRecord(*rec2);
349+
wxLogMessage("copyMissingWaveRecords. Create GribRecord: %p", r2);
337350
r2->setRecordCurrentDate(date);
338351
storeRecordInMap(r2);
339352
}
@@ -455,6 +468,7 @@ void GribReader::readGribFileContent() {
455468

456469
// Crée un GribRecord avec les dewpoints calculés
457470
GribRecord *recDewpoint = new GribRecord(*recModel);
471+
wxLogMessage("readGribFileContent. Create GribRecord: %p", recDewpoint);
458472
recDewpoint->setDataType(GRB_DEWPOINT);
459473
for (zuint i = 0; i < (zuint)recModel->getNi(); i++) {
460474
for (zuint j = 0; j < (zuint)recModel->getNj(); j++) {

plugins/grib_pi/src/GribReader.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,20 @@ class GribReader {
8585

8686
enum GribFileDataStatus { DATA_IN_FILE, NO_DATA_IN_FILE, COMPUTED_DATA };
8787

88+
/**
89+
* Initializes cumulative meteorological parameters by copying their first record values.
90+
*
91+
* This establishes a proper baseline for accumulation parameters like total precipitation
92+
* and cloud cover, preventing artificial zero-value periods.
93+
*/
8894
void copyFirstCumulativeRecord();
8995
// void removeFirstCumulativeRecord ();
96+
/**
97+
* Fills gaps in wave-related data fields by propagating known values across missing time periods.
98+
*
99+
* This function handles multiple wave parameters including significant height, direction and period,
100+
* ensuring continuous visualization of marine conditions.
101+
*/
90102
void copyMissingWaveRecords();
91103
void copyFirstCumulativeRecord(int dataType, int levelType, int levelValue);
92104
// void removeFirstCumulativeRecord (int dataType,int levelType,int
@@ -120,6 +132,13 @@ class GribReader {
120132
void clean_vector(std::vector<GribRecord *> &ls);
121133
void clean_all_vectors();
122134
std::vector<GribRecord *> *getFirstNonEmptyList();
135+
// GribRecords can be shared between different vectors in mapGribRecords.
136+
// Several of the storeRecordInMap() calls in readAllGribRecords() can store
137+
// the same GribRecord pointer in multiple vectors.
138+
// This means when we try to clean up in clean_vector(), we could end up with
139+
// double deletes of the same pointer.
140+
// To avoid this, we keep track of which GribRecords have been deleted.
141+
std::set<GribRecord*> deletedRecords;
123142

124143
// Interpolation between 2 GribRecord
125144
double get2GribsInterpolatedValueByDate(double px, double py, time_t date,

plugins/grib_pi/src/GribRecord.h

Lines changed: 114 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ class GribCode {
151151
//----------------------------------------------
152152
class GribRecord {
153153
public:
154+
/** Copy constructor performs a deep copy of the GribRecord. */
154155
GribRecord(const GribRecord &rec);
155156
GribRecord() { m_bfilled = false; }
156157

@@ -272,39 +273,146 @@ class GribRecord {
272273
int &Nj, int &rec1offi, int &rec1offj,
273274
int &rec2offi, int &rec2offj);
274275

275-
int id; // unique identifiant
276-
bool ok; // valid?
277-
bool knownData; // type de donnée connu
276+
/**
277+
* Unique identifier for this record.
278+
*
279+
* Set during file reading for original records.
280+
* Monotonically increasing for records read from file.
281+
*/
282+
int id;
283+
/**
284+
* Indicates record validity.
285+
*
286+
* A record may be invalid if source records have mismatched dimensions,
287+
* missing data arrays, failed interpolation, or the source records themselves
288+
* are invalid when creating derived records.
289+
*/
290+
bool ok;
291+
/**
292+
* Indicates whether the data type in this record is recognized by the parser.
293+
* Used to skip unknown data types during processing.
294+
*/
295+
bool knownData;
296+
/**
297+
* Differentiates wave-related parameters (height, direction, period) from
298+
* other meteorological data for specialized processing.
299+
*/
278300
bool waveData;
301+
/**
302+
* Indicates if this record was created through copying rather than direct
303+
* reading.
304+
*
305+
* Tracks whether this record was copied to maintain data continuity. This
306+
* happens with wave data gaps or initial values for cumulative parameters.
307+
*/
279308
bool IsDuplicated;
309+
/**
310+
* Signals when the end of the GRIB file has been reached during parsing.
311+
*/
280312
bool eof;
313+
/**
314+
* Unique string identifier constructed from data type, level type, and level
315+
* value. Used for record lookup and comparison.
316+
*/
281317
std::string dataKey;
282318
char strRefDate[32];
283319
char strCurDate[32];
320+
/**
321+
* Identifies the numerical weather model that produced this data.
322+
*
323+
* Standard WMO values from GRIB2 Table C-11 include:
324+
* - 7: US National Weather Service, National Centers for Environmental
325+
* Prediction (NCEP)
326+
* - 34: Japanese Meteorological Agency - Tokyo (JMA)
327+
* - 58: European Centre for Medium-Range Weather Forecasts (ECMWF)
328+
* - 59: DWD (German Weather Service)
329+
* - 85: French Weather Service (Meteo France)
330+
* - 251: Norwegian Meteorological Institute
331+
*/
284332
int dataCenterModel;
333+
/**
334+
* Indicates whether the data array has been populated. Used to track
335+
* partial loading states during record construction.
336+
*/
285337
bool m_bfilled;
286338

287339
//---------------------------------------------
288340
// SECTION 0: THE INDICATOR SECTION (IS)
289341
//---------------------------------------------
342+
/**
343+
* GRIB edition number, indicating the version of the GRIB specification used.
344+
* Determines how subsequent sections should be parsed.
345+
*/
290346
zuchar editionNumber;
291347

292348
// SECTION 1: THE PRODUCT DEFINITION SECTION (PDS)
349+
/**
350+
* Originating center ID as defined by WMO common table C-1.
351+
* Identifies which meteorological center generated the forecast.
352+
*/
293353
zuchar idCenter;
354+
/**
355+
* Model identifier within the originating center.
356+
* Distinguishes between different forecast models run by the same center.
357+
*/
294358
zuchar idModel;
359+
/**
360+
* Grid identifier used by the originating center.
361+
* Specifies the coordinate system and projection of the data grid.
362+
*/
295363
zuchar idGrid;
364+
/**
365+
* Parameter identifier as defined by GRIB tables.
366+
* Specifies what physical quantity is represented (wind, temperature, etc).
367+
*/
296368
zuchar dataType; // octet 9 = parameters and units
369+
/**
370+
* Vertical level type indicator.
371+
* Specifies the type of vertical coordinate (pressure level, height above
372+
* ground, etc).
373+
*/
297374
zuchar levelType;
375+
/**
376+
* Numeric value associated with levelType.
377+
* For example, the specific pressure level in hectopascals.
378+
*/
298379
zuint levelValue;
299380

381+
/**
382+
* Indicates presence of a bitmap section.
383+
* When true, the data section uses a bitmap to indicate valid data points.
384+
*/
300385
bool hasBMS;
386+
/**
387+
* Components of the reference time for this forecast.
388+
* Specifies when the forecast model was initialized.
389+
*/
301390
zuint refyear, refmonth, refday, refhour, refminute;
302391
// zuchar periodP1, periodP2;
392+
/**
393+
* Time range indicators for this forecast step.
394+
* Used to calculate the valid time period for this data.
395+
*/
303396
zuint periodP1, periodP2;
397+
/**
398+
* Statistical processing indicator.
399+
* Describes how the data was processed over time (e.g., accumulation,
400+
* average).
401+
*/
304402
zuchar timeRange;
305-
zuint periodsec; // period in seconds
306-
time_t refDate; // C reference date
307-
time_t curDate; // C current date
403+
/**
404+
* Forecast period in seconds.
405+
* Time offset from the reference time.
406+
*/
407+
zuint periodsec;
408+
/**
409+
* Unix timestamp of model initialization time.
410+
*/
411+
time_t refDate;
412+
/**
413+
* Unix timestamp of when this forecast is valid.
414+
*/
415+
time_t curDate;
308416
// SECTION 2: THE GRID DESCRIPTION SECTION (GDS)
309417
zuchar NV, PV;
310418
zuchar gridType;

0 commit comments

Comments
 (0)