void DataManager::print_firstRecord_info(void) { if(grib) { GribRecord * rec = grib->getFirstRecord(); if(rec) { qWarning() << "edition=" << rec->get_editionNumber() << ", center=" << rec->get_idCenter() << ", model=" << rec->get_idModel() << ", grid=" << rec->get_idGrid(); } } }
void DataManager::print_firstRecord_bmap(void) { if(grib) { GribRecord * rec = grib->getFirstRecord(); if(rec) { rec->print_bitmap(); qWarning() << "bmapSize=" << rec->get_bmapSize() << ", dataSize=" << rec->get_dataSize(); } } }
//--------------------------------------------------- // Rectangle de la zone couverte par les données bool GribReader::getZoneExtension(double *x0,double *y0, double *x1,double *y1) { std::vector<GribRecord *> *ls = getFirstNonEmptyList(); if (ls != NULL) { GribRecord *rec = ls->at(0); if (rec != NULL) { *x0 = rec->getX(0); *y0 = rec->getY(0); *x1 = rec->getX( rec->getNi()-1 ); *y1 = rec->getY( rec->getNj()-1 ); if (*x0 > *x1) { double tmp = *x0; *x0 = *x1; *x1 = tmp; } if (*y0 > *y1) { double tmp = *y0; *y0 = *y1; *y1 = tmp; } } return true; } else { return false; } }
//------------------------------------------------------------- // Grille GRIB void GribPlot::draw_GridPoints (const DataCode &dtc, QPainter &pnt, const Projection *proj) { if (gribReader == NULL) { return; } // GribRecord *rec = gribReader->getFirstGribRecord (); DataCode dd; if (dtc.dataType == GRB_PRV_WIND_XY2D) dd = DataCode (GRB_WIND_VX, dtc.levelType, dtc.levelValue); else if (dtc.dataType == GRB_PRV_CUR_XY2D) dd = DataCode (GRB_CUR_VX, dtc.levelType, dtc.levelValue); else dd = dtc; GribRecord *rec = gribReader->getRecord (dd, getCurrentDate()); if (! rec) return; int px,py, i,j, dl=2; for (i=0; i<rec->getNi(); i++) for (j=0; j<rec->getNj(); j++) { //if (rec->hasValue(i,j)) { proj->map2screen(rec->getX(i), rec->getY(j), &px,&py); pnt.drawLine(px-dl,py, px+dl,py); pnt.drawLine(px,py-dl, px,py+dl); proj->map2screen(rec->getX(i)-360.0, rec->getY(j), &px,&py); pnt.drawLine(px-dl,py, px+dl,py); pnt.drawLine(px,py-dl, px,py+dl); } } }
//--------------------------------------------------------------------------------- void GribReader::readGribFileContent() { fileSize = zu_filesize(file); readAllGribRecords(); createListDates(); // hoursBetweenRecords = computeHoursBeetweenGribRecords(); //----------------------------------------------------- // Are dewpoint data in file ? // If no, compute it with Magnus-Tetens formula, if possible. //----------------------------------------------------- dewpointDataStatus = DATA_IN_FILE; if (getNumberOfGribRecords(GRB_DEWPOINT, LV_ABOV_GND, 2) == 0) { dewpointDataStatus = NO_DATA_IN_FILE; if ( getNumberOfGribRecords(GRB_HUMID_REL, LV_ABOV_GND, 2) > 0 && getNumberOfGribRecords(GRB_TEMP, LV_ABOV_GND, 2) > 0) { dewpointDataStatus = COMPUTED_DATA; std::set<time_t>::iterator iter; for (iter=setAllDates.begin(); iter!=setAllDates.end(); iter++) { time_t date = *iter; GribRecord *recModel = getGribRecord(GRB_TEMP,LV_ABOV_GND,2,date); if (recModel != NULL) { // Crée un GribRecord avec les dewpoints calculés GribRecord *recDewpoint = new GribRecord(*recModel); if (recDewpoint != NULL) { recDewpoint->setDataType(GRB_DEWPOINT); for (zuint i=0; i<(zuint)recModel->getNi(); i++) for (zuint j=0; j<(zuint)recModel->getNj(); j++) { double x = recModel->getX(i); double y = recModel->getY(j); double dp = computeDewPoint(x, y, date); recDewpoint->setValue(i, j, dp); } storeRecordInMap(recDewpoint); } } } } } //----------------------------------------------------- }
//------------------------------------------------------------------ void GribReader::findGribsAroundDate (int dataType,int levelType,int levelValue, time_t date, GribRecord **before, GribRecord **after) { // Cherche les GribRecord qui encadrent la date std::vector<GribRecord *> *ls = getListOfGribRecords(dataType,levelType,levelValue); *before = NULL; *after = NULL; zuint nb = ls->size(); for (zuint i=0; i<nb && *before==NULL && *after==NULL; i++) { GribRecord *rec = (*ls)[i]; if (rec->getRecordCurrentDate() == date) { *before = rec; *after = rec; } else if (rec->getRecordCurrentDate() < date) { *before = rec; } else if (rec->getRecordCurrentDate() > date && *before != NULL) { *after = rec; } } }
//------------------------------------------------------- double GribReader::computeDewPoint(double lon, double lat, time_t now) { double diewpoint = GRIB_NOTDEF; GribRecord *recTempDiew = getGribRecord(GRB_DEWPOINT,LV_ABOV_GND,2,now); if (recTempDiew != NULL) { // GRIB file contains diew point data diewpoint = recTempDiew->getInterpolatedValue(lon, lat); } else { // Compute diew point with Magnus-Tetens formula GribRecord *recTemp = getGribRecord(GRB_TEMP,LV_ABOV_GND,2,now); GribRecord *recHumid = getGribRecord(GRB_HUMID_REL,LV_ABOV_GND,2,now); if (recTemp && recHumid) { double temp = recTemp->getInterpolatedValue(lon, lat); double humid = recHumid->getInterpolatedValue(lon, lat); if (temp != GRIB_NOTDEF && humid != GRIB_NOTDEF) { double a = 17.27; double b = 237.7; double t = temp-273.15; double rh = humid; //if ( t>0 && t<60 && rh>0.01) { double alpha = a*t/(b+t)+log(rh/100.0); diewpoint = b*alpha/(a-alpha); diewpoint += 273.15; } } } } return diewpoint; }
GRIBFile::GRIBFile( const wxString file_name, bool CumRec, bool WaveRec ) { m_bOK = true; // Assume ok until proven otherwise if( !::wxFileExists( file_name ) ) { m_last_message = _( "Error: File does not exist!" ); m_bOK = false; return; } // Use the zyGrib support classes, as (slightly) modified locally.... m_pGribReader = new GribReader(); // Read and ingest the entire GRIB file....... m_pGribReader->openFile( file_name ); if( !m_pGribReader->isOk() ) { m_last_message = _( "Error: Can't read this File!" ); m_bOK = false; return; } m_FileName = file_name; if( CumRec ) m_pGribReader->copyFirstCumulativeRecord(); //add missing records if option selected if( WaveRec ) m_pGribReader->copyMissingWaveRecords (); // "" "" m_nGribRecords = m_pGribReader->getTotalNumberOfGribRecords(); // Walk the GribReader date list to populate our array of GribRecordSets std::set<time_t>::iterator iter; std::set<time_t> date_list = m_pGribReader->getListDates(); for( iter = date_list.begin(); iter != date_list.end(); iter++ ) { GribRecordSet *t = new GribRecordSet(); time_t reftime = *iter; t->m_Reference_Time = reftime; m_GribRecordSetArray.Add( t ); } // Convert from zyGrib organization by data type/level to our organization by time. GribRecord *pRec; // Get the map of GribRecord vectors std::map<std::string, std::vector<GribRecord *>*> *p_map = m_pGribReader->getGribMap(); // Iterate over the map to get vectors of related GribRecords std::map<std::string, std::vector<GribRecord *>*>::iterator it; for( it = p_map->begin(); it != p_map->end(); it++ ) { std::vector<GribRecord *> *ls = ( *it ).second; for( zuint i = 0; i < ls->size(); i++ ) { pRec = ls->at( i ); time_t thistime = pRec->getRecordCurrentDate(); // Search the GribRecordSet array for a GribRecordSet with matching time for( unsigned int j = 0; j < m_GribRecordSetArray.GetCount(); j++ ) { if( m_GribRecordSetArray.Item( j ).m_Reference_Time == thistime ) { int idx = -1; switch(pRec->getDataType()) { case GRB_WIND_VX: idx = Idx_WIND_VX; break; case GRB_WIND_VY: idx = Idx_WIND_VY; break; case GRB_WIND_GUST: idx = Idx_WIND_GUST; break; case GRB_PRESSURE: idx = Idx_PRESSURE; break; case GRB_HTSGW: idx = Idx_HTSIGW; break; case GRB_WVDIR: idx = Idx_WVDIR; break; case GRB_USCT: idx = Idx_WINDSCAT_VX; break; case GRB_VSCT: idx = Idx_WINDSCAT_VY; break; case GRB_UOGRD: idx = Idx_SEACURRENT_VX; break; case GRB_VOGRD: idx = Idx_SEACURRENT_VY; break; case GRB_PRECIP_TOT: idx = Idx_PRECIP_TOT; break; case GRB_CLOUD_TOT: idx = Idx_CLOUD_TOT; break; case GRB_TEMP: idx = Idx_AIR_TEMP_2M; break; case GRB_WTMP: idx = Idx_SEA_TEMP; break; } if(idx != -1) m_GribRecordSetArray.Item( j ).m_GribRecordPtrArray[idx]= pRec; break; } } } } }
//--------------------------------------------------------------------------------- void GribReader::readAllGribRecords() { //-------------------------------------------------------- // Lecture de l'ensemble des GribRecord du fichier // et stockage dans les listes appropriées. //-------------------------------------------------------- GribRecord *rec; int id = 0; time_t firstdate = -1; bool b_EOF; do { id ++; rec = new GribRecord(file, id); assert(rec); if (rec->isOk()) { b_EOF = rec->isEof(); if (rec->isDataKnown()) { ok = true; // au moins 1 record ok if (firstdate== -1) firstdate = rec->getRecordCurrentDate(); /* if (//----------------------------------------- (rec->getDataType()==GRB_PRESSURE && rec->getLevelType()==LV_MSL && rec->getLevelValue()==0) //----------------------------------------- || ( (rec->getDataType()==GRB_TMIN || rec->getDataType()==GRB_TMAX) && rec->getLevelType()==LV_ABOV_GND && rec->getLevelValue()==2) //----------------------------------------- || (rec->getDataType()==GRB_TEMP && rec->getLevelType()==LV_ABOV_GND && rec->getLevelValue()==2) || (rec->getDataType()==GRB_TEMP && rec->getLevelType()==LV_ISOBARIC && ( rec->getLevelValue()==850 || rec->getLevelValue()==700 || rec->getLevelValue()==500 || rec->getLevelValue()==300 ) ) //----------------------------------------- || ( (rec->getDataType()==GRB_WIND_VX || rec->getDataType()==GRB_WIND_VY) && rec->getLevelType()==LV_ABOV_GND && rec->getLevelValue()==10) || ( (rec->getDataType()==GRB_WIND_VX || rec->getDataType()==GRB_WIND_VY) && rec->getLevelType()==LV_ISOBARIC && ( rec->getLevelValue()==850 || rec->getLevelValue()==700 || rec->getLevelValue()==500 || rec->getLevelValue()==300 ) ) //----------------------------------------- || (rec->getDataType()==GRB_HUMID_SPEC && rec->getLevelType()==LV_ISOBARIC && ( rec->getLevelValue()==850 || rec->getLevelValue()==700 || rec->getLevelValue()==500 || rec->getLevelValue()==300 ) ) //----------------------------------------- || (rec->getDataType()==GRB_GEOPOT_HGT && rec->getLevelType()==LV_ISOTHERM0 && rec->getLevelValue()==0) || (rec->getDataType()==GRB_GEOPOT_HGT && rec->getLevelType()==LV_ISOBARIC && ( rec->getLevelValue()==850 || rec->getLevelValue()==700 || rec->getLevelValue()==500 || rec->getLevelValue()==300 ) ) //----------------------------------------- || (rec->getDataType()==GRB_PRECIP_TOT && rec->getLevelType()==LV_GND_SURF && rec->getLevelValue()==0) //----------------------------------------- || (rec->getDataType()==GRB_PRECIP_RATE && rec->getLevelType()==LV_GND_SURF && rec->getLevelValue()==0) //----------------------------------------- || (rec->getDataType()==GRB_SNOW_DEPTH && rec->getLevelType()==LV_GND_SURF && rec->getLevelValue()==0) //----------------------------------------- || (rec->getDataType()==GRB_SNOW_CATEG && rec->getLevelType()==LV_GND_SURF && rec->getLevelValue()==0) //----------------------------------------- || (rec->getDataType()==GRB_FRZRAIN_CATEG && rec->getLevelType()==LV_GND_SURF && rec->getLevelValue()==0) //----------------------------------------- || (rec->getDataType()==GRB_CLOUD_TOT && rec->getLevelType()==LV_ATMOS_ALL && rec->getLevelValue()==0) //----------------------------------------- || (rec->getDataType()==GRB_HUMID_REL && rec->getLevelType()==LV_ABOV_GND && rec->getLevelValue()==2) //----------------------------------------- || (rec->getDataType()==GRB_TPOT && rec->getLevelType()==LV_SIGMA && rec->getLevelValue()==9950) //----------------------------------------- || (rec->getDataType()==GRB_CAPE && rec->getLevelType()==LV_GND_SURF && rec->getLevelValue()==0) ) */ if (//----------------------------------------- (rec->getDataType()==GRB_PRESSURE && rec->getLevelType()==LV_MSL && rec->getLevelValue()==0) || ( (rec->getDataType()==GRB_WIND_VX || rec->getDataType()==GRB_WIND_VY) && rec->getLevelType()==LV_ABOV_GND && rec->getLevelValue()==10) ) { storeRecordInMap(rec); } else if( (rec->getDataType()==GRB_WIND_GUST && rec->getLevelType()==LV_GND_SURF && rec->getLevelValue()==0) ) storeRecordInMap(rec); else if( (rec->getDataType()==GRB_WIND_VX || rec->getDataType()==GRB_WIND_VY) && rec->getLevelType()==LV_GND_SURF) storeRecordInMap(rec); else if( rec->getDataType()==GRB_TEMP //Air temperature at 2m && rec->getLevelType()==LV_ABOV_GND && rec->getLevelValue()==2 ) storeRecordInMap(rec); else if(rec->getDataType()==GRB_PRECIP_TOT //total rainfall && rec->getLevelType()==LV_GND_SURF && rec->getLevelValue()==0 ) storeRecordInMap(rec); else if(rec->getDataType()==GRB_CLOUD_TOT //cloud cover && rec->getLevelType()==LV_ATMOS_ALL && rec->getLevelValue()==0 ) storeRecordInMap(rec); else if( rec->getDataType() == GRB_HTSGW ) // Significant Wave Height storeRecordInMap(rec); else if( rec->getDataType() == GRB_WVDIR ) // Wind Wave Direction storeRecordInMap(rec); else if( rec->getDataType() == GRB_USCT ) // Scatterometer U Wind Estimate storeRecordInMap(rec); else if( rec->getDataType() == GRB_VSCT ) // Scatterometer V Wind Estimate storeRecordInMap(rec); else if( rec->getDataType() == GRB_CRAIN ) // Catagorical Rain 1/0 storeRecordInMap(rec); //else if ((rec->getDataType()==GRB_TEMP) && (rec->getLevelType()==LV_GND_SURF) && (rec->getLevelValue()==0)) // storeRecordInMap(rec); // gfs SEATMP else if ((rec->getDataType()==GRB_WTMP) && (rec->getLevelType()==LV_GND_SURF) && (rec->getLevelValue()==0)) storeRecordInMap(rec); // rtofs Water Temp + translated gfs Water Temp else if( (rec->getDataType()==GRB_UOGRD || rec->getDataType()==GRB_VOGRD)) // rtofs model sea current current storeRecordInMap(rec); else { /* fprintf(stderr, "GribReader: unknown record type: dataType=%d levelType=%d levelValue=%d idCenter==%d && idModel==%d && idGrid==%d\n", rec->getDataType(), rec->getLevelType(), rec->getLevelValue(), rec->getIdCenter(), rec->getIdModel(), rec->getIdGrid() ); */ delete rec; } } } else { // ! rec-isOk delete rec; rec = NULL; } } while (rec != NULL && !b_EOF); }
bool GribRecord::GetInterpolatedParameters (const GribRecord &rec1, const GribRecord &rec2, double &La1, double &Lo1, double &La2, double &Lo2, double &Di, double &Dj, int &im1, int &jm1, int &im2, int &jm2, int &Ni, int &Nj, int &rec1offi, int &rec1offj, int &rec2offi, int &rec2offj ) { if(!rec1.isOk() || !rec2.isOk()) return false; /* make sure Dj both have same sign */ if(rec1.getDj() * rec2.getDj() <= 0) return false; Di = wxMax(rec1.getDi(), rec2.getDi()); Dj = rec1.getDj() > 0 ? wxMax(rec1.getDj(), rec2.getDj()): wxMin(rec1.getDj(), rec2.getDj()); /* get overlapping region */ if(Dj > 0) La1 = wxMax(rec1.La1, rec2.La1), La2 = wxMin(rec1.La2, rec2.La2); else La1 = wxMin(rec1.La1, rec2.La1), La2 = wxMax(rec1.La2, rec2.La2); Lo1 = wxMax(rec1.Lo1, rec2.Lo1), Lo2 = wxMin(rec1.Lo2, rec2.Lo2); // align gribs on integer boundaries int i, j; // shut up compiler warning 'may be used uninitialized' // rec2.Dj / rec1.Dj > 0 // XXX Is it true for rec2.Di / rec1.Di ? double rec1offdi = 0, rec2offdi = 0; double rec1offdj = 0., rec2offdj = 0.; double iiters = rec2.Di / rec1.Di; if(iiters < 1) { iiters = 1/iiters; im1 = 1, im2 = iiters; } else im1 = iiters, im2 = 1; for(i=0; i<iiters; i++) { rec1offdi = (Lo1 - rec1.Lo1)/rec1.Di; rec2offdi = (Lo1 - rec2.Lo1)/rec2.Di; if(rec1offdi == floor(rec1offdi) && rec2offdi == floor(rec2offdi)) break; Lo1 += wxMin(rec1.Di, rec2.Di); } if(i == iiters) // failed to align, would need spacial interpolation to work return false; double jiters = rec2.Dj / rec1.Dj; if(jiters < 1) { jiters = 1/jiters; jm1 = 1, jm2 = iiters; } else jm1 = jiters, jm2 = 1; for(j=0; j<jiters; j++) { rec1offdj = (La1 - rec1.La1)/rec1.Dj; rec2offdj = (La1 - rec2.La1)/rec2.Dj; if(rec1offdj == floor(rec1offdj) && rec2offdj == floor(rec2offdj)) break; La1 += Dj < 0 ? wxMax(rec1.getDj(), rec2.getDj()): wxMin(rec1.getDj(), rec2.getDj()); } if(j == jiters) // failed to align return false; /* no overlap */ if(La1*Dj > La2*Dj || Lo1 > Lo2) return false; /* compute integer sizes for data array */ Ni = (Lo2-Lo1)/Di + 1, Nj = (La2-La1)/Dj + 1; /* back-compute final La2 and Lo2 to fit this integer boundary */ Lo2 = Lo1 + (Ni-1)*Di, La2 = La1 + (Nj-1)*Dj; rec1offi = rec1offdi, rec2offi = rec2offdi; rec1offj = rec1offdj, rec2offj = rec2offdj; if (!rec1.data || !rec2.data) return false; return true; }
//================================================================================== // Flèches de direction du current //================================================================================== void GribPlot::draw_CURRENT_Arrows ( Altitude altitude, QColor arrowsColor, QPainter &pnt, const Projection *proj ) { if (gribReader == NULL) { return; } currentAltitude = altitude; currentArrowColor = arrowsColor; GribRecord *recx = gribReader->getRecord (DataCode(GRB_CUR_VX,altitude),currentDate); GribRecord *recy = gribReader->getRecord (DataCode(GRB_CUR_VY,altitude),currentDate); if (recx == NULL || recy == NULL) return; int i, j; double x, y, vx, vy; int W = proj->getW(); int H = proj->getH(); int space; space = drawCurrentArrowsOnGrid ? currentArrowSpaceOnGrid : currentArrowSpace; if (drawCurrentArrowsOnGrid) { // Flèches uniquement sur les points de la grille int oldi=-1000, oldj=-1000; for (int gi=0; gi<recx->getNi(); gi++) { x = recx->getX(gi); y = recx->getY(0); proj->map2screen(x,y, &i,&j); if (true || abs(i-oldi)>=space) { oldi = i; for (int gj=0; gj<recx->getNj(); gj++) { x = recx->getX(gi); y = recx->getY(gj); proj->map2screen(x,y, &i,&j); //---------------------------------------------------------------------- if (! recx->isXInMap(x)) x += 360.0; // tour du monde ? if (recx->isPointInMap(x,y)) { if (true || abs(j-oldj)>=space) { oldj = j; vx = recx->getInterpolatedValue(x, y, mustInterpolateValues); vy = recy->getInterpolatedValue(x, y, mustInterpolateValues); if (vx != GRIB_NOTDEF && vy != GRIB_NOTDEF) { drawCurrentArrow(pnt, i,j, vx,vy); } } } } } } } else { // Flèches uniformément réparties sur l'écran for (i=0; i<W; i+=space) { for (j=0; j<H; j+=space) { proj->screen2map(i,j, &x,&y); //---------------------------------------------------------------------- if (! recx->isXInMap(x)) x += 360.0; // tour du monde ? if (recx->isPointInMap(x,y)) { vx = recx->getInterpolatedValue(x, y, mustInterpolateValues); vy = recy->getInterpolatedValue(x, y, mustInterpolateValues); if (vx != GRIB_NOTDEF && vy != GRIB_NOTDEF) { drawCurrentArrow(pnt, i,j, vx,vy); } } //---------------------------------------------------------------------- } } } }