23 return (time1 - time0) / 3600.0;
36 if (! strchr(initialOfNames,
'u') || ! strchr(initialOfNames,
'v')) {
39 bool hasG = (strchr(initialOfNames,
'g') != NULL);
40 bool hasW = (strchr(initialOfNames,
'w') != NULL);
45 size_t nValues = nPoints * nComp;
47 float *arr = malloc(nValues *
sizeof(
float));
48 if (!arr)
return NULL;
57 arr[idx++] = gribData[iGrib].
u;
58 arr[idx++] = gribData[iGrib].
v;
59 if (hasG) arr[idx++] = gribData[iGrib].
g;
60 if (hasW) arr[idx++] = gribData[iGrib].
w;
71 printf (
"printGribAll\n");
74 printf (
"Time: %.0lf\n", t);
75 printf (
"lon lat u v g w\n");
79 printf (
" %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f\n", \
80 gribData [iGrib].lon, \
81 gribData [iGrib].lat, \
94 const int maxUV = 100;
122 ((zone2->
latMin < zone1 -> latMax) &&
123 (zone2->
latMax > zone1 -> latMin) &&
124 (zone2->
lonLeft < zone1 -> lonRight) &&
125 (zone2->
lonRight > zone1 -> lonLeft));
132 const time_t timeMax1 = timeMin1 + 3600 * (zone1-> timeStamp [zone1 -> nTimeStamp -1]);
133 const time_t timeMax2 = timeMin2 + 3600 * (zone2-> timeStamp [zone2 -> nTimeStamp -1]);
135 return (timeMin2 < timeMax1) && (timeMax2 > timeMin1);
156 bool uPresent =
false, vPresent =
false;
165 return uPresent && vPresent;
193 if (fabs (lat -
tGribData [iFlow][iGrib].lat) > epsilon) {
196 if (fabs (lon -
tGribData [iFlow][iGrib].lon) > epsilon) {
208 const double windEpsilon = 0.01;
209 const double currentEpsilon = 0.1;
211 int nVal = 0, nLatSuspects, nLonSuspects;
214 const char *separator =
"----------------------------------------------------------------------------------";
215 snprintf (str,
MAX_SIZE_LINE,
"\n%s\nCheck Grib Info: %s\n%s\n", separator, (type ==
WIND) ?
"Wind" :
"Current", separator);
219 snprintf (str,
MAX_SIZE_LINE,
"No %s grib available\n", (type ==
WIND) ?
"Wind" :
"Current");
235 snprintf (str,
MAX_SIZE_LINE,
"Expected numberofValues = nbLon x nbLat = %ld, but numberOfValues = %ld\n",\
241 snprintf (str,
MAX_SIZE_LINE,
"Expected difference between lonLeft and lonRight is %.2lf, found: %.2lf\n",\
247 snprintf (str,
MAX_SIZE_LINE,
"Expected difference between latMax and latMin is %.2lf, found: %.2lf\n",\
257 nVal =
consistentGrib (
zone, type, (type ==
WIND) ? windEpsilon : currentEpsilon, &nLatSuspects, &nLonSuspects);
258 if ((nLatSuspects > 0) || (nLonSuspects > 0)) {
260 snprintf (str,
MAX_SIZE_LINE,
"n Val suspect Lat: %d, ratio: %.2lf %% \n", nLatSuspects, 100 * (
double)nLatSuspects/(
double) (nVal));
262 snprintf (str,
MAX_SIZE_LINE,
"n Val suspect Lon: %d, ratio: %.2lf %% \n", nLonSuspects, 100 * (
double)nLonSuspects/(
double) (nVal));
278 snprintf (str,
MAX_SIZE_LINE,
"timeStep is NOT REGULAR !!!\n");
285 snprintf (str,
MAX_SIZE_LINE,
"out zone Values: %d, ratio: %.2lf %% \n", sCheck.
outZone, 100 * (
double)sCheck.
outZone/(
double) (nVal));
321 if (OK) buffer [0] =
'\0';
322 if (!hasCurrentGrib)
return OK;
324 if (OK) buffer [0] =
'\0';
330 snprintf (str,
MAX_SIZE_LINE,
"\nCurrent and wind grib have no common geo\n");
336 snprintf (str,
MAX_SIZE_LINE,
"\nCurrent and wind grib have no common time\n");
346 if (t <= zone->timeStamp [0]) {
357 if (t < zone->timeStamp [k]) {
369 return ((
double) floor (v/step)) * step;
374 return ((
double) ceil (v/step)) * step;
379 double *latMax,
double *lonMin,
double *lonMax,
Zone *
zone) {
405 if (lon < zone->lonLeft) lon += 360.0;
410static bool findFlow (
double lat,
double lon,
double t,
double *rU,
double *rV, \
414 double latMin, latMax, lonMin, lonMax;
415 double a, b, u0, u1, v0, v1, g0, g1, w0, w1;
417 FlowP windP00, windP01, windP10, windP11;
419 *rU = 0, *rV = 0, *rG = 0; *rW = 0;
488void findWindGrib (
double lat,
double lon,
double t,
double *u,
double *v, \
489 double *gust,
double *w,
double *twd,
double *tws ) {
496 *gust = hypot (*u, *v);
500 *twd =
fTwd (*u, *v);
501 *tws =
fTws (*u, *v);
508 double *vCurr,
double *tcd,
double *tcs) {
525 *tcd =
fTwd (*uCurr, *vCurr);
526 *tcs =
fTws (*uCurr, *vCurr);
542 snprintf (str, maxLen,
"Centre ID: %ld %s %s Ed number: %ld\nnMessages: %d\nstepUnits: %ld\n# values : %ld\n",\
544 snprintf (line,
MAX_SIZE_LINE,
"Zone From: %s, %s To: %s, %s\n",\
594 struct tm tm_buf, *tm_info;
595 char strTime [20] =
"1970-01-01 00:00:00";
600 if (stat (gribName, &st) != 0) {
601 fprintf (stderr,
"In gribToStrJson Error stat: %s\n", gribName);
602 snprintf (out, maxLen,
"{}\n");
606 fprintf (stderr,
"In gribToStrJson Error reading: %s\n", gribName);
607 snprintf (out, maxLen,
"{}\n");
611 fprintf (stderr,
"In gribToStrJson Error reading: %s\n", gribName);
612 snprintf (out, maxLen,
"{}\n");
615 if (gZone.
nbLat == 0) {
616 fprintf (stderr,
"In gribToStrJson Error no value available in: %s\n", gribName);
617 snprintf (out, maxLen,
"{}\n");
629 snprintf (out, maxLen,
630 "{\n \"centreID\": %ld, \"centreName\": \"%s\", \"edNumber\": %ld, \n"
631 " \"runStart\": \"%s\", \"runEnd\": \"%s\", \n"
632 " \"epochStart\": %ld,\n"
633 " \"topLat\": %.6f, \"leftLon\": %.6f, \"bottomLat\": %.6f, \"rightLon\": %.6f, \n"
634 " \"latStep\": %.4f, \"lonStep\": %.4f, \n"
635 " \"nLat\": %ld, \"nLon\": %ld, \"nValues\": %ld, \"nTimeStamp\": %zu,\n"
636 " \"timeStamps\": \n [",
645 for (
size_t i = 0; i < gZone.
nTimeStamp; i += 1) {
646 snprintf (str,
sizeof (str),
"%ld%s", gZone.
timeStamp [i], (i < gZone.
nTimeStamp -1) ?
", " :
"");
651 snprintf (str,
sizeof (str),
" \"nShortName\": %zu, \"shortNames\": [", gZone.
nShortName);
654 for (
size_t i = 0; i < gZone.
nShortName; i += 1) {
655 snprintf (str,
sizeof (str),
"\"%s\"%s", gZone.
shortName [i], (i < gZone.
nShortName -1) ?
", " :
"");
660 tm_info = localtime_r (&st.st_mtime, &tm_buf);
661 if (tm_info) strftime(strTime,
sizeof strTime,
"%Y-%m-%d %H:%M:%S", tm_info);
664 snprintf (str,
sizeof (str),
" \"name\": \"%s\", \"fileSize\": %ld, \"fileTime\": \"%s\",\n",
665 gribBaseName, st.st_size, strTime);
670 snprintf (infoStr,
sizeof (infoStr),
"Warning number of Date: %zu, number of Time: %zu", gZone.
nDataDate, gZone.
nDataTime);
672 snprintf (str,
sizeof (str),
" \"info\": \"%s\"\n}\n", infoStr);
#define g_strlcat(dest, src, size)
#define g_strlcpy(dest, src, size)
static char * g_path_get_basename(const char *path)
close to Glib g_path_get_basename
static bool isInZone(double lat, double lon, Zone *zone)
true if P (lat, lon) is within the zone
static double interpolate(double x, double x0, double x1, double fx0, double fx1)
return fx : linear interpolation
static double fTwd(double u, double v)
true wind direction
static double lonCanonize(double lon)
return lon on ]-180, 180 ] interval
static double fTws(double u, double v)
true wind speed.
#define EPSILON
compilation: gcc -c grib.c pkg-config --cflags glib-2.0
static int consistentGrib(const Zone *zone, int iFlow, double epsilon, int *nLatSuspects, int *nLonSuspects)
check lat, lon are consistent with indice return number of values
static bool findFlow(double lat, double lon, double t, double *rU, double *rV, double *rG, double *rW, Zone *zone, const FlowP *gribData)
interpolation to get u, v, g (gust), w (waves) at point (lat, lon) and time t
bool uvPresentGrib(const Zone *zone)
true if u and v (or uCurr, vCurr) are in zone
void findCurrentGrib(double lat, double lon, double t, double *uCurr, double *vCurr, double *tcd, double *tcs)
use findflow to get current
char * gribToStr(const Zone *zone, char *str, size_t maxLen)
write Grib information in string
static long indLat(double lat, const Zone *zone)
return indice of lat in gribData wind or current
static bool timeIntersectGrib(const Zone *zone1, const Zone *zone2)
true if (wind) zone and zone 2 intersect in time
static bool checkGrib(const Zone *zone, int iFlow, CheckGrib *check)
static double arrondiMax(double v, double step)
ex arrondiMax (46.4, 0.25) = 46.50
void printGrib(const Zone *zone, const FlowP *gribData)
print Grib u v ... for all lat lon time information
static void findTimeAround(double t, int *iTInf, int *iTSup, const Zone *zone)
find iTinf and iTsup in order t : zone.timeStamp [iTInf] <= t <= zone.timeStamp [iTSup]
bool isPresentGrib(const Zone *zone, const char *name)
true if shortname in zone
bool checkGribToStr(bool hasCurrentGrib, char *buffer, size_t maxLen)
check Grib information and write report in the buffer return false if something wrong
static void find4PointsAround(double lat, double lon, double *latMin, double *latMax, double *lonMin, double *lonMax, Zone *zone)
provide 4 wind points around point lat, lon
char * gribToStrJson(const char *fileName, char *out, size_t maxLen)
write grib meta information in string
double zoneTimeDiff(const Zone *zone1, const Zone *zone0)
return difference in hours between two zones (current zone and Wind zone)
static bool geoIntersectGrib(const Zone *zone1, const Zone *zone2)
true if (wind) zone and currentZone intersect in geography
static long indLon(double lon, const Zone *zone)
return indice of lon in gribData wind or current
static bool timeStepRegularGrib(const Zone *zone)
check if time steps are regular
bool checkGribInfoToStr(int type, Zone *zone, char *buffer, size_t maxLen)
check Grib information and write (add) report in the buffer return false if something wrong
float * buildUVGWarray(const Zone *zone, const char *initialOfNames, const FlowP *gribData, size_t *outNValues)
return array of outNvalues floats n = nTimeStamp * nbLat * nbLon * nShortNames values = [u1,...
void findWindGrib(double lat, double lon, double t, double *u, double *v, double *gust, double *w, double *twd, double *tws)
use findflow to get wind and waves
static double arrondiMin(double v, double step)
ex arrondiMin (46.4, 0.25) = 46.25
#define MAX_SIZE_FILE_NAME
char * lonToStr(double lon, int type, char *str, size_t maxLen)
convert lon to str according to type
char * buildRootName(const char *fileName, char *rootName, size_t maxLen)
Build root name if not already a root name.
char * newDate(long intDate, double nHours, char *res, size_t maxLen)
return date and time using ISO notation after adding myTime (hours) to the Date
Zone zone
geographic zone covered by grib file
const struct MeteoElmt meteoTab[N_METEO_ADMIN]
dictionnary of meteo services
char * latToStr(double lat, int type, char *str, size_t maxLen)
convert lat to str according to type
time_t gribDateTimeToEpoch(long date, long hhmm)
convert long date/time from GRIB to time_t (UTC, via timegm)
FlowP * tGribData[]
grib data description
bool readGribLists(const char *fileName, Zone *zone)
Read lists zone.timeStamp, shortName, zone.dataDate, dataTime before full grib reading.
bool readGribParameters(const char *fileName, Zone *zone)
Read grib parameters in zone before full grib reading.
long dataTime[MAX_N_DATA_TIME]
char shortName[MAX_N_SHORT_NAME][MAX_SIZE_SHORT_NAME]
long timeStamp[MAX_N_TIME_STAMPS]
long dataDate[MAX_N_DATA_DATE]