LCOV - code coverage report
Current view: top level - frmts/grib/degrib/degrib - metaprint.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 0 62 0.0 %
Date: 2024-04-27 14:28:19 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /*****************************************************************************
       2             :  * metaprint.c
       3             :  *
       4             :  * DESCRIPTION
       5             :  *    This file contains the code necessary to write out the meta data
       6             :  * structure.
       7             :  *
       8             :  * HISTORY
       9             :  *    9/2002 Arthur Taylor (MDL / RSIS): Created.
      10             :  *
      11             :  * NOTES
      12             :  * 1) Need to add support for GS3_ORTHOGRAPHIC = 90,
      13             :  *    GS3_EQUATOR_EQUIDIST = 110, GS3_AZIMUTH_RANGE = 120
      14             :  * 2) Need to add support for GS4_RADAR = 20, GS4_SATELLITE = 30
      15             :  *****************************************************************************
      16             :  */
      17             : #include <stdio.h>
      18             : #include <stdlib.h>
      19             : #include <stdarg.h>
      20             : #include <math.h>
      21             : #ifndef DONT_DEPRECATE_SPRINTF
      22             : #define DONT_DEPRECATE_SPRINTF
      23             : #endif
      24             : #include "cpl_port.h"
      25             : #include "meta.h"
      26             : #include "metaname.h"
      27             : #include "myerror.h"
      28             : #include "myutil.h"
      29             : #if 0
      30             : /* tdlpack is no longer supported by GDAL */
      31             : #include "tdlpack.h"
      32             : #endif
      33             : #include "myassert.h"
      34             : #include "clock.h"
      35             : 
      36             : /*****************************************************************************
      37             :  * Lookup() --
      38             :  *
      39             :  * Arthur Taylor / MDL
      40             :  *
      41             :  * PURPOSE
      42             :  *   To lookup the string value in a table, given the table, the index, and
      43             :  * some default values.
      44             :  *
      45             :  * ARGUMENTS
      46             :  * table = The table to look in. (Input)
      47             :  *     n = Size of table. (Input)
      48             :  * index = Index to look up. (Input)
      49             :  *
      50             :  * FILES/DATABASES: None
      51             :  *
      52             :  * RETURNS: char *
      53             :  *   The desired index value, or the appropriate default message.
      54             :  *
      55             :  * HISTORY
      56             :  *   9/2002 Arthur Taylor (MDL/RSIS): Created.
      57             :  *
      58             :  * NOTES
      59             :  * Can not do a sizeof(table) here because table is now of arbitrary length.
      60             :  * Instead do sizeof(table) in calling procedure.
      61             :  *****************************************************************************
      62             :  */
      63             : #if 0  // Unused with GDAL.
      64             : static const char *Lookup(const char * const *table, size_t n, size_t index)
      65             : {
      66             :    static const char * const def[] =
      67             :     { "Reserved", "Reserved for local use", "Missing" };
      68             :    if (index < (n / sizeof (char *))) {
      69             :       return table[index];
      70             :    } else if (index < 192) {
      71             :       return def[0];
      72             :    } else if (index < 255) {
      73             :       return def[1];
      74             :    } else {
      75             :       return def[2];
      76             :    }
      77             : }
      78             : #endif
      79             : 
      80             : /*****************************************************************************
      81             :  * Print() --
      82             :  *
      83             :  * Arthur Taylor / MDL
      84             :  *
      85             :  * PURPOSE
      86             :  *   To print the message to a local static array in a way similar to
      87             :  * myerror.c::errSprintf.  This allows us to pass the results back to Tcl/Tk,
      88             :  * as well as to save it to disk.  It also serves as a central place to
      89             :  * change if we want a different style of output.
      90             :  *
      91             :  *   The caller gives a series of calls with fmt != NULL, followed by
      92             :  * a fmt == NULL.  This last call will return the constructed message to the
      93             :  * caller, and reset the message to NULL.  It is caller's responsibility to
      94             :  * free the message, and to make sure that last call to Print has fmt = NULL,
      95             :  * so that the routine doesn't accidentally keep memory.
      96             :  *
      97             :  * ARGUMENTS
      98             :  *   label = A label for this set of data. (Input)
      99             :  * varName = A char string describing the variable.. (Input)
     100             :  *     fmt = Prt_NULL, Prt_D, Prt_DS, Prt_DSS, Prt_S, Prt_F, Prt_FS, Prt_E,
     101             :  *           Prt_ES. (Input)
     102             :  *           determines what to expect in the rest of the arguments.
     103             :  *           d = sInt4, s = char *, f = double,
     104             :  *           NULL = return the constructed answer, and reset answer to NULL.
     105             :  *
     106             :  * FILES/DATABASES: None
     107             :  *
     108             :  * RETURNS: char *
     109             :  *   NULL if (fmt != NULL) (i.e. we added to message)
     110             :  *   message if (fmt == NULL) (i.e. return the message).
     111             :  *       It is caller's responsibility to free the message, and to make sure
     112             :  *       that last call to Print has fmt = NULL.
     113             :  *
     114             :  * HISTORY
     115             :  *   9/2002 Arthur Taylor (MDL/RSIS): Created.
     116             :  *   4/2003 AAT: Changed so it could print different types of labels
     117             :  *               "GDS" instead of "S3"
     118             :  *  10/2004 AAT: Added Prt_SS
     119             :  *
     120             :  * NOTES
     121             :  * Using enumerated type instead of "ds" "dss" etc.  For speed considerations.
     122             :  *****************************************************************************
     123             :  */
     124           0 : char *Print(const char *label, const char *varName, int fmt, ...)
     125             : {
     126             :    static char *buffer = nullptr; /* Copy of message generated so far. */
     127             :    va_list ap;          /* pointer to variable argument list. */
     128             :    sInt4 lival;         /* Store a sInt4 val from argument list. */
     129             :    char *sval;          /* Store a string val from argument. */
     130             :    char *unit;          /* Second string val is usually a unit string. */
     131             :    double dval;         /* Store a double val from argument list. */
     132             :    char *ans;           /* Final message to return if fmt = Prt_NULL. */
     133             : 
     134           0 :    if (fmt == Prt_NULL) {
     135           0 :       ans = buffer;
     136           0 :       buffer = nullptr;
     137           0 :       return ans;
     138             :    }
     139           0 :    va_start (ap, fmt);  /* make ap point to 1st unnamed arg. */
     140           0 :    switch (fmt) {
     141           0 :       case Prt_D:
     142           0 :          lival = va_arg (ap, sInt4);
     143           0 :          reallocSprintf (&buffer, "%s | %s | %ld\n", label, varName, lival);
     144           0 :          break;
     145           0 :       case Prt_DS:
     146           0 :          lival = va_arg (ap, sInt4);
     147           0 :          sval = va_arg (ap, char *);
     148           0 :          reallocSprintf (&buffer, "%s | %s | %ld (%s)\n", label, varName,
     149             :                          lival, sval);
     150           0 :          break;
     151           0 :       case Prt_DSS:
     152           0 :          lival = va_arg (ap, sInt4);
     153           0 :          sval = va_arg (ap, char *);
     154           0 :          unit = va_arg (ap, char *);
     155           0 :          reallocSprintf (&buffer, "%s | %s | %ld (%s [%s])\n", label,
     156             :                          varName, lival, sval, unit);
     157           0 :          break;
     158           0 :       case Prt_S:
     159           0 :          sval = va_arg (ap, char *);
     160           0 :          reallocSprintf (&buffer, "%s | %s | %s\n", label, varName, sval);
     161           0 :          break;
     162           0 :       case Prt_SS:
     163           0 :          sval = va_arg (ap, char *);
     164           0 :          unit = va_arg (ap, char *);
     165           0 :          reallocSprintf (&buffer, "%s | %s | %s (%s)\n", label, varName,
     166             :                          sval, unit);
     167           0 :          break;
     168           0 :       case Prt_F:
     169           0 :          dval = va_arg (ap, double);
     170           0 :          reallocSprintf (&buffer, "%s | %s | %f\n", label, varName, dval);
     171           0 :          break;
     172           0 :       case Prt_E:
     173           0 :          dval = va_arg (ap, double);
     174           0 :          reallocSprintf (&buffer, "%s | %s | %e\n", label, varName, dval);
     175           0 :          break;
     176           0 :       case Prt_G:
     177           0 :          dval = va_arg (ap, double);
     178           0 :          reallocSprintf (&buffer, "%s | %s | %g\n", label, varName, dval);
     179           0 :          break;
     180           0 :       case Prt_FS:
     181           0 :          dval = va_arg (ap, double);
     182           0 :          unit = va_arg (ap, char *);
     183           0 :          reallocSprintf (&buffer, "%s | %s | %f (%s)\n", label, varName,
     184             :                          dval, unit);
     185           0 :          break;
     186           0 :       case Prt_ES:
     187           0 :          dval = va_arg (ap, double);
     188           0 :          unit = va_arg (ap, char *);
     189           0 :          reallocSprintf (&buffer, "%s | %s | %e (%s)\n", label, varName,
     190             :                          dval, unit);
     191           0 :          break;
     192           0 :       case Prt_GS:
     193           0 :          dval = va_arg (ap, double);
     194           0 :          unit = va_arg (ap, char *);
     195           0 :          reallocSprintf (&buffer, "%s | %s | %g (%s)\n", label, varName,
     196             :                          dval, unit);
     197           0 :          break;
     198           0 :       default:
     199           0 :          reallocSprintf (&buffer, "ERROR: Invalid Print option '%d'\n", fmt);
     200             :    }
     201           0 :    va_end (ap);         /* clean up when done. */
     202           0 :    return nullptr;
     203             : }
     204             : 
     205             : #if 0  // Unused with GDAL.
     206             : /*****************************************************************************
     207             :  * PrintSect1() --
     208             :  *
     209             :  * Arthur Taylor / MDL
     210             :  *
     211             :  * PURPOSE
     212             :  *   To generate the message for GRIB2 section 1.
     213             :  *
     214             :  * ARGUMENTS
     215             :  *      pds2 = The GRIB2 Product Definition Section to print. (Input)
     216             :  *    center = The Center that created the data (Input)
     217             :  * subcenter = The Sub Center that created the data (Input)
     218             :  *
     219             :  * FILES/DATABASES: None
     220             :  *
     221             :  * RETURNS: void
     222             :  *
     223             :  * HISTORY
     224             :  *   9/2002 Arthur Taylor (MDL/RSIS): Created.
     225             :  *   4/2003 AAT: Changed to accept pointer to pdsG2Type pds2
     226             :  *  10/2005 AAT: Adjusted to take center, subcenter as we moved that out of
     227             :  *               the pdsG2 type.
     228             :  *
     229             :  * NOTES
     230             :  *****************************************************************************
     231             :  */
     232             : static void PrintSect1 (pdsG2Type * pds2, unsigned short int center,
     233             :                         unsigned short int subcenter)
     234             : {
     235             :    /* Based on Grib2 Code Table 1.2 */
     236             :    static const char * const table12[] = { "Analysis", "Start of Forecast",
     237             :       "Verifying time of forecast", "Observation time"
     238             :    };
     239             : 
     240             :    /* Based on Grib2 Code Table 1.3 */
     241             :    static const char * const table13[] = { "Operational products",
     242             :       "Operational test products", "Research products",
     243             :       "Re-analysis products"
     244             :    };
     245             : 
     246             :    /* Based on Grib2 Code Table 1.4 */
     247             :    static const char * const table14[] = { "Analysis products",
     248             :       "Forecast products", "Analysis and forecast products",
     249             :       "Control forecast products", "Perturbed forecast products",
     250             :       "Control and perturbed forecast products",
     251             :       "Processed satellite observations", "Processed radar observations"
     252             :    };
     253             : 
     254             :    char buffer[25];     /* Stores format of pds2->refTime. */
     255             :    const char *ptr;
     256             : 
     257             :    ptr = centerLookup (center);
     258             :    if (ptr != NULL) {
     259             :       Print ("PDS-S1", "Originating center", Prt_DS, center, ptr);
     260             :    } else {
     261             :       Print ("PDS-S1", "Originating center", Prt_D, center);
     262             :    }
     263             :    if (subcenter != GRIB2MISSING_u2) {
     264             :       ptr = subCenterLookup (center, subcenter);
     265             :       if (ptr != NULL) {
     266             :          Print ("PDS-S1", "Originating sub-center", Prt_DS, subcenter, ptr);
     267             :       } else {
     268             :          Print ("PDS-S1", "Originating sub-center", Prt_D, subcenter);
     269             :       }
     270             :    }
     271             :    Print ("PDS-S1", "GRIB Master Tables Version", Prt_D, pds2->mstrVersion);
     272             :    Print ("PDS-S1", "GRIB Local Tables Version", Prt_D, pds2->lclVersion);
     273             :    Print ("PDS-S1", "Significance of reference time", Prt_DS, pds2->sigTime,
     274             :           Lookup (table12, sizeof (table12), pds2->sigTime));
     275             : 
     276             : /*   strftime (buffer, 25, "%m/%d/%Y %H:%M:%S UTC", gmtime (&(pds2->refTime)));*/
     277             :    Clock_Print (buffer, 25, pds2->refTime, "%m/%d/%Y %H:%M:%S UTC", 0);
     278             : 
     279             :    Print ("PDS-S1", "Reference Time", Prt_S, buffer);
     280             :    Print ("PDS-S1", "Operational Status", Prt_DS, pds2->operStatus,
     281             :           Lookup (table13, sizeof (table13), pds2->operStatus));
     282             :    Print ("PDS-S1", "Type of Data", Prt_DS, pds2->dataType,
     283             :           Lookup (table14, sizeof (table14), pds2->dataType));
     284             : }
     285             : 
     286             : /*****************************************************************************
     287             :  * PrintSect2() --
     288             :  *
     289             :  * Arthur Taylor / MDL
     290             :  *
     291             :  * PURPOSE
     292             :  *   To generate a message for the section 2 data.  This may be more
     293             :  * appropriate in its own file (particularly the weather table.)
     294             :  *
     295             :  * ARGUMENTS
     296             :  * sect2 = The sect2 structure to print (initialized by ParseSect2). (Input)
     297             :  *
     298             :  * FILES/DATABASES: None
     299             :  *
     300             :  * RETURNS: void
     301             :  *
     302             :  * HISTORY
     303             :  *   2/2003 Arthur Taylor (MDL/RSIS): Created.
     304             :  *
     305             :  * NOTES
     306             :  *****************************************************************************
     307             :  */
     308             : static void PrintSect2 (sect2_type * sect2)
     309             : {
     310             :    size_t i;            /* loop counter over number of sect2 data. */
     311             :    char buffer[25];     /* Assists with labeling. */
     312             : 
     313             :    switch (sect2->ptrType) {
     314             :       case GS2_WXTYPE:
     315             :          Print ("PDS-S2", "Number of Elements in Section 2", Prt_D,
     316             :                 sect2->wx.dataLen);
     317             :          for (i = 0; i < sect2->wx.dataLen; i++) {
     318             :             if (sect2->wx.ugly[i].validIndex != -1) {
     319             :                sprintf (buffer, "Elem %3d  Is Used", (int) i);
     320             :             } else {
     321             :                sprintf (buffer, "Elem %3d NOT Used", (int) i);
     322             :             }
     323             :             Print ("PDS-S2", buffer, Prt_S, sect2->wx.data[i]);
     324             :          }
     325             :          break;
     326             :       case GS2_UNKNOWN:
     327             :          Print ("PDS-S2", "Number of Elements in Section 2", Prt_D,
     328             :                 sect2->unknown.dataLen);
     329             :          for (i = 0; i < sect2->unknown.dataLen; i++) {
     330             :             sprintf (buffer, "Element %d", (int) i);
     331             :             Print ("PDS-S2", buffer, Prt_F, sect2->unknown.data[i]);
     332             :          }
     333             :          break;
     334             :       default:
     335             :          return;
     336             :    }
     337             : }
     338             : 
     339             : /*****************************************************************************
     340             :  * PrintSect4_Category() --
     341             :  *
     342             :  * Arthur Taylor / MDL
     343             :  *
     344             :  * PURPOSE
     345             :  *   To generate the category message for section 4.
     346             :  *
     347             :  * ARGUMENTS
     348             :  * meta = The meta file structure to generate the message for. (Input)
     349             :  *
     350             :  * FILES/DATABASES: None
     351             :  *
     352             :  * RETURNS: void
     353             :  *
     354             :  * HISTORY
     355             :  *   6/2003 Arthur Taylor (MDL/RSIS): Extracted this part from PrintSect4().
     356             :  *   1/2004 AAT: Combined PrintSect4_Meteo and PrintSect4_Ocean into this.
     357             :  *   5/2004 AAT: Found out that I skipped "Momentum Probabilities" in tbl41_0.
     358             :  *
     359             :  * NOTES
     360             :  *****************************************************************************
     361             :  */
     362             : static void PrintSect4_Category_OAR (uChar cat) {
     363             :    if (cat == 2) {
     364             :       Print ("PDS-S4", "Category Description", Prt_DS, cat, "Lightning Products");
     365             :    } else if (cat == 3) {
     366             :       Print ("PDS-S4", "Category Description", Prt_DS, cat, "Severe Weather Products");
     367             :    } else if (cat == 4) {
     368             :       Print ("PDS-S4", "Category Description", Prt_DS, cat, "Satellite Products");
     369             :    } else if (cat == 5) {
     370             :       Print ("PDS-S4", "Category Description", Prt_DS, cat, "Forecast Products");
     371             :    } else if (cat == 6) {
     372             :       Print ("PDS-S4", "Category Description", Prt_DS, cat, "Precipitation Products");
     373             :    } else if (cat == 7) {
     374             :       Print ("PDS-S4", "Category Description", Prt_DS, cat, "Model-based Products");
     375             :    } else if (cat == 8) {
     376             :       Print ("PDS-S4", "Category Description", Prt_DS, cat, "Intermediate Products");
     377             :    } else if (cat == 9) {
     378             :       Print ("PDS-S4", "Category Description", Prt_DS, cat, "3D Reflectivity Mosaics");
     379             :    } else if (cat == 10) {
     380             :       Print ("PDS-S4", "Category Description", Prt_DS, cat, "Composite Reflectivity Mosaics");
     381             :    } else if (cat == 11) {
     382             :       Print ("PDS-S4", "Category Description", Prt_DS, cat, "Other Reflectivity Mosaics");
     383             :    } else  {
     384             :       Print ("PDS-S4", "Category Description", Prt_DS, cat, "unknown");
     385             :    }
     386             : }
     387             : 
     388             : static void PrintSect4_Category (grib_MetaData *meta)
     389             : {
     390             :    sect4_type *sect4 = &(meta->pds2.sect4);
     391             : 
     392             :    /* Based on Grib2 Code Table 4.1 discipline 0 */
     393             :    static const char * const tbl41_0[] = {
     394             :       "Temperature", "Moisture", "Momentum", "Mass", "Short-wave Radiation",
     395             :       "Long-wave Radiation", "Cloud", "Thermodynamic Stability indices",
     396             :       "Kinematic Stability indices", "Temperature Probabilities",
     397             :       "Moisture Probabilities", "Momentum Probabilities",
     398             :       "Mass Probabilities", "Aerosols", "Trace gases (e.g. ozone, C02)",
     399             :       "Radar", "Forecast Radar Imagery", "Electro-dynamics",
     400             :       "Nuclear/radiology", "Physical atmospheric properties",
     401             :       "Atmospheric chemical Constituents",
     402             :    };
     403             :    /* Based on Grib2 Code Table 4.1 discipline 1 */
     404             :    static const char * const tbl41_1[] = {
     405             :       "Hydrology basic products", "Hydrology probabilities"
     406             :    };
     407             :    /* Based on Grib2 Code Table 4.1 discipline 2 */
     408             :    static const char * const tbl41_2[] = {
     409             :       "Vegetation/Biomass", "Agri-/aquacultural Special Products",
     410             :       "Transportation-related Products", "Soil Products"
     411             :    };
     412             :    /* Based on Grib2 Code Table 4.1 discipline 3 */
     413             :    static const char * const tbl41_3[] = {
     414             :       "Image format products", "Quantitative products"
     415             :    };
     416             :    /* Based on Grib2 Code Table 4.1 discipline 10 */
     417             :    static const char * const tbl41_10[] = {
     418             :       "Waves", "Currents", "Ice", "Surface Properties",
     419             :       "Sub-surface Properties"
     420             :    };
     421             : 
     422             :    if (meta->pds2.mstrVersion == 255) {
     423             :       if (meta->center == 161) {
     424             :          PrintSect4_Category_OAR(sect4->cat);
     425             :       } else {
     426             :          Print ("PDS-S4", "Category Description", Prt_DS, sect4->cat, "unknown");
     427             :       }
     428             :       return;
     429             :    }
     430             :    switch (meta->pds2.prodType) {
     431             :       case 0:          /* Meteo category. */
     432             :          switch (sect4->cat) {
     433             :             case 190:
     434             :                Print ("PDS-S4", "Category Description", Prt_DS, sect4->cat,
     435             :                       "CCITT IA5 string");
     436             :                break;
     437             :             case 191:
     438             :                Print ("PDS-S4", "Category Description", Prt_DS, sect4->cat,
     439             :                       "Miscellaneous");
     440             :                break;
     441             :             case 192:
     442             :                Print ("PDS-S4", "Category Description", Prt_DS, sect4->cat,
     443             :                       "Covariance");
     444             :                break;
     445             :             default:
     446             :                Print ("PDS-S4", "Category Description", Prt_DS, sect4->cat,
     447             :                       Lookup (tbl41_0, sizeof (tbl41_0), sect4->cat));
     448             :          }
     449             :          break;
     450             :       case 1:          /* Hydrological */
     451             :          Print ("PDS-S4", "Category Description", Prt_DS, sect4->cat,
     452             :                 Lookup (tbl41_1, sizeof (tbl41_1), sect4->cat));
     453             :          break;
     454             :       case 2:          /* Land surface */
     455             :          Print ("PDS-S4", "Category Description", Prt_DS, sect4->cat,
     456             :                 Lookup (tbl41_2, sizeof (tbl41_2), sect4->cat));
     457             :          break;
     458             :       case 3:          /* Space */
     459             :          switch (sect4->cat) {
     460             :             case 192:
     461             :                Print ("PDS-S4", "Category Description", Prt_DS, sect4->cat,
     462             :                       "Forecast Satellite Imagery");
     463             :                break;
     464             :             default:
     465             :                Print ("PDS-S4", "Category Description", Prt_DS, sect4->cat,
     466             :                       Lookup (tbl41_3, sizeof (tbl41_3), sect4->cat));
     467             :          }
     468             :          break;
     469             :       case 10:         /* Oceanographic */
     470             :          switch (sect4->cat) {
     471             :             case 191:
     472             :                Print ("PDS-S4", "Category Description", Prt_DS, sect4->cat,
     473             :                       "Miscellaneous");
     474             :                break;
     475             :             default:
     476             :                Print ("PDS-S4", "Category Description", Prt_DS, sect4->cat,
     477             :                       Lookup (tbl41_10, sizeof (tbl41_10), sect4->cat));
     478             :          }
     479             :          break;
     480             :       default:
     481             :          Print ("PDS-S4", "PrintSect4() does not handle this prodType",
     482             :                 Prt_D, meta->pds2.prodType);
     483             :    }
     484             : }
     485             : 
     486             : /*****************************************************************************
     487             :  * PrintSect4() --
     488             :  *
     489             :  * Arthur Taylor / MDL
     490             :  *
     491             :  * PURPOSE
     492             :  *   To generate the message for section 4.
     493             :  *
     494             :  * ARGUMENTS
     495             :  *   meta = The meta file structure to generate the message for. (Input)
     496             :  * f_unit = 0 (GRIB unit), 1 (english), 2 (metric) (Input)
     497             :  *
     498             :  * FILES/DATABASES: None
     499             :  *
     500             :  * RETURNS: int (could use errSprintf())
     501             :  *  0 if no error.
     502             :  * -2 if asked to print data for a template that we don't support.
     503             :  *
     504             :  * HISTORY
     505             :  *   9/2002 Arthur Taylor (MDL/RSIS): Created.
     506             :  *   2/2003 AAT: Adjusted the interpretation of the scale vector and value.
     507             :  *          to be consistent with what Matt found from email conversations
     508             :  *          with WMO GRIB2 experts.
     509             :  *   2/2003 AAT: Switched from: value / pow (10, factor)
     510             :  *                          to: value * pow (10, -1 * factor)
     511             :  *   6/2003 AAT: Extracted the prodType = 0 only info and put in _Meteo
     512             :  *   6/2003 AAT: Created a PrintSect4_Ocean for ocean stuff.
     513             :  *   1/2004 AAT: Updated table 4.7
     514             :  *   1/2004 AAT: Modified to use "comment" from metaname.c instead of
     515             :  *          PrintSect4_Meteo, and PrintSect4_Ocean (that way local tables are
     516             :  *          enabled.) (Fixed meta file for PoP12).
     517             :  *   3/2004 AAT: Added emphasis on "computation" of unit conversion.
     518             :  *   3/2005 AAT: Added support for GS4_PROBABIL_PNT
     519             :  *
     520             :  * NOTES
     521             :  * Need to add support for GS4_RADAR = 20
     522             :  *****************************************************************************
     523             :  */
     524             : static int PrintSect4 (grib_MetaData *meta, sChar f_unit)
     525             : {
     526             :    sect4_type *sect4 = &(meta->pds2.sect4);
     527             :    /* Based on Grib2 Code Table 4.0 */
     528             :    static const char * const tbl40[] = {
     529             :       "Analysis at a horizontal layer at a point in time",
     530             :       "Individual ensemble forecast at a horizontal layer at a point in time",
     531             :       "Derived forecast based on ensemble members at a horizontal layer at a"
     532             :             " point in time",
     533             :       "Probability forecast at a horizontal layer or level at a point in "
     534             :             "time",
     535             :       "Percentile forecasts at a horizontal layer or level at a point in "
     536             :             "time",
     537             :       "Statistically processed data at a horizontal layer or level in a time"
     538             :             " interval",
     539             :       "Probability forecast at a horizontal layer or level in a time "
     540             :             "interval",
     541             :       "Percentile forecasts at a horizontal layer or level in a time "
     542             :             "interval",
     543             :       "Individual ensemble forecast at a horizontal layer or level in a time"
     544             :             " interval",
     545             :       "Derived forecasts based in all ensemble members at a horizontal level "
     546             :             "or layer in a time interval",
     547             :       "Radar product", "Satellite product"
     548             :    };
     549             : 
     550             :    /* Based on Grib2 Code Table 4.3 */
     551             :    static const char * const tbl43[] = {
     552             :       "Analysis", "Initialization", "Forecast", "Bias corrected forecast",
     553             :       "Ensemble forecast", "Probability forecast", "Forecast error",
     554             :       "Analysis error", "Observation"
     555             :    };
     556             : 
     557             :    /* Based on Grib2 Code Table 4.4 */
     558             :    static const char * const tbl44[] = {
     559             :       "Minute", "Hour", "Day", "Month", "Year", "Decade",
     560             :       "Normal (30 years)", "Century", "Reserved", "Reserved",
     561             :       "3 hours", "6 hours", "12 hours", "Second"
     562             :    };
     563             : 
     564             :    /* Based on Grib2 Code Table 4.5 */
     565             :    /* See "metaname.c :: Surface[]" */
     566             : 
     567             :    /* Based on Grib2 Code Table 4.6 */
     568             :    static const char * const tbl46[] = {
     569             :       "Unperturbed high-resolution control forecast",
     570             :       "Unperturbed low-resolution control forecast",
     571             :       "Negatively perturbed forecast", "Positively perturbed forecast"
     572             :    };
     573             : 
     574             :    /* Based on Grib2 Code Table 4.7 */
     575             :    static const char * const tbl47[] = {
     576             :       "Unweighted mean of all members", "Weighted mean of all members",
     577             :       "Standard deviation with respect to cluster mean",
     578             :       "Standard deviation with respect to cluster mean, normalized",
     579             :       "Spread of all members",
     580             :       "Large anomaly index of all members",
     581             :       "Unweighted mean of the cluster members"
     582             :    };
     583             : 
     584             :    /* Based on Grib2 Code Table 4.9 */
     585             :    static const char * const tbl49[] = {
     586             :       "Probability of event below lower limit",
     587             :       "Probability of event above upper limit",
     588             :       "Probability of event between limits (include lower, exclude upper)",
     589             :       "Probability of event above lower limit",
     590             :       "Probability of event below upper limit"
     591             :    };
     592             : 
     593             :    /* Based on Grib2 Code Table 4.10 */
     594             :    static const char * const tbl410[] = {
     595             :       "Average", "Accumulation", "Maximum", "Minimum",
     596             :       "Difference (Value at end of time minus beginning)",
     597             :       "Root mean square", "Standard deviation",
     598             :       "Covariance (Temporal variance)",
     599             :       "Difference (Value at beginning of time minus end)", "Ratio",
     600             :       "Standardized Anomaly", "Summation", "Confidence Index",
     601             :       "Quality Indicator"
     602             :    };
     603             : 
     604             :    /* Based on Grib2 Code Table 4.11 */
     605             :    static const char * const tbl411[] = {
     606             :       "Reserved",
     607             :       "Successive times; same forecast time, start time incremented",
     608             :       "Successive times; same start time, forecast time incremented",
     609             :       "Successive times; start time incremented, forecast time decremented, "
     610             :             "valid time constant",
     611             :       "Successive times; start time decremented, forecast time incremented, "
     612             :             "valid time constant",
     613             :       "Floating subinterval of time between forecast time, and end"
     614             :    };
     615             : 
     616             :    char buffer[50];     /* Temp storage for various uses including time
     617             :                          * format. */
     618             :    int i;               /* counter for templat 4.8/4.9 for num time range
     619             :                          * specs. */
     620             :    int f_reserved;      /* Whether Table4.5 is a reserved entry or not. */
     621             :    GRIB2SurfTable surf; /* Surface look up in Table4.5. */
     622             :    const char *ptr;
     623             : 
     624             :    switch (sect4->templat) {
     625             :       case GS4_ANALYSIS:
     626             :       case GS4_ERROR:
     627             :       case GS4_ENSEMBLE:
     628             :       case GS4_DERIVED:
     629             :          Print ("PDS-S4", "Product type", Prt_DS, sect4->templat,
     630             :                 tbl40[sect4->templat]);
     631             :          break;
     632             :       case GS4_PROBABIL_PNT:
     633             :          Print ("PDS-S4", "Product type", Prt_DS, sect4->templat, tbl40[3]);
     634             :          break;
     635             :       case GS4_PERCENT_PNT:
     636             :          Print ("PDS-S4", "Product type", Prt_DS, sect4->templat, tbl40[4]);
     637             :          break;
     638             :       case GS4_STATISTIC:
     639             :          Print ("PDS-S4", "Product type", Prt_DS, sect4->templat, tbl40[5]);
     640             :          break;
     641             :       case GS4_PROBABIL_TIME:
     642             :          Print ("PDS-S4", "Product type", Prt_DS, sect4->templat, tbl40[6]);
     643             :          break;
     644             :       case GS4_PERCENT_TIME:
     645             :          Print ("PDS-S4", "Product type", Prt_DS, sect4->templat, tbl40[7]);
     646             :          break;
     647             :       case GS4_ENSEMBLE_STAT:
     648             :          Print ("PDS-S4", "Product type", Prt_DS, sect4->templat, tbl40[8]);
     649             :          break;
     650             :       case GS4_DERIVED_INTERVAL:
     651             :          Print ("PDS-S4", "Product type", Prt_DS, sect4->templat, tbl40[9]);
     652             :          break;
     653             : /*
     654             :  * The following lines were removed until such time that the rest of this
     655             :  * procedure can properly handle this template type.
     656             :  *
     657             :       case GS4_RADAR:
     658             :          Print ("PDS-S4", "Product type", Prt_DS, sect4->templat, tbl40[10]);
     659             :          break;
     660             : */
     661             :       case GS4_SATELLITE:
     662             :          Print ("PDS-S4", "Product type", Prt_DS, sect4->templat, tbl40[11]);
     663             :          break;
     664             :       default:
     665             :          Print ("PDS-S4", "Product type", Prt_D, sect4->templat);
     666             :          errSprintf ("Un-supported Sect4 template %ld\n", sect4->templat);
     667             :          return -2;
     668             :    }
     669             : 
     670             :    PrintSect4_Category (meta);
     671             :    Print ("PDS-S4", "Category Sub-Description", Prt_DS, sect4->subcat,
     672             :           meta->comment);
     673             : 
     674             :    if (f_unit == 1) {
     675             :       Print ("PDS-S4", "Output grid, (COMPUTED) english unit is", Prt_S,
     676             :              meta->unitName);
     677             :    } else if (f_unit == 2) {
     678             :       Print ("PDS-S4", "Output grid, (COMPUTED) metric unit is", Prt_S,
     679             :              meta->unitName);
     680             :    }
     681             :    Print ("PDS-S4", "Generation process", Prt_DS, sect4->genProcess,
     682             :           Lookup (tbl43, sizeof (tbl43), sect4->genProcess));
     683             :    if (sect4->templat == GS4_SATELLITE) {
     684             :       Print ("PDS-S4", "Observation generating process", Prt_D, sect4->genID);
     685             :       Print ("PDS-S4", "Number of contributing spectral bands", Prt_D,
     686             :              sect4->numBands);
     687             :       for (i = 0; i < sect4->numBands; i++) {
     688             :          Print ("PDS-S4", "Satellite series", Prt_D, sect4->bands[i].series);
     689             :          Print ("PDS-S4", "Satellite numbers", Prt_D,
     690             :                 sect4->bands[i].numbers);
     691             :          Print ("PDS-S4", "Instrument type", Prt_D, sect4->bands[i].instType);
     692             :          Print ("PDS-S4", "Scale Factor of central wave number", Prt_D,
     693             :                 sect4->bands[i].centWaveNum.factor);
     694             :          Print ("PDS-S4", "Scale Value of central wave number", Prt_D,
     695             :                 sect4->bands[i].centWaveNum.value);
     696             :       }
     697             :       return 0;
     698             :    }
     699             :    if (sect4->bgGenID != GRIB2MISSING_u1) {
     700             :       ptr = processLookup (meta->center, sect4->bgGenID);
     701             :       if (ptr != NULL) {
     702             :          Print ("PDS-S4", "Background generating process ID", Prt_DS,
     703             :                 sect4->bgGenID, ptr);
     704             :       } else {
     705             :          Print ("PDS-S4", "Background generating process ID", Prt_D,
     706             :                 sect4->bgGenID);
     707             :       }
     708             :    }
     709             :    if (sect4->genID != GRIB2MISSING_u1) {
     710             :       ptr = processLookup (meta->center, sect4->genID);
     711             :       if (ptr != NULL) {
     712             :          Print ("PDS-S4", "Forecast generating process ID", Prt_DS,
     713             :                 sect4->genID, ptr);
     714             :       } else {
     715             :          Print ("PDS-S4", "Forecast generating process ID", Prt_D,
     716             :                 sect4->genID);
     717             :       }
     718             :    }
     719             :    if (sect4->f_validCutOff) {
     720             :       Print ("PDS-S4", "Data cut off after reference time in seconds", Prt_D,
     721             :              sect4->cutOff);
     722             :    }
     723             :    Print ("PDS-S4", "Forecast time in hours", Prt_F,
     724             :           (double) (sect4->foreSec / 3600.));
     725             :    surf = Table45Index (sect4->fstSurfType, &f_reserved, meta->center,
     726             :                         meta->subcenter);
     727             :    Print ("PDS-S4", "Type of first fixed surface", Prt_DSS,
     728             :           sect4->fstSurfType, surf.comment, surf.unit);
     729             :    Print ("PDS-S4", "Value of first fixed surface", Prt_F,
     730             :           sect4->fstSurfValue);
     731             :    if (sect4->sndSurfType != GRIB2MISSING_u1) {
     732             :       surf = Table45Index (sect4->sndSurfType, &f_reserved, meta->center,
     733             :                            meta->subcenter);
     734             :       Print ("PDS-S4", "Type of second fixed surface", Prt_DSS,
     735             :              sect4->sndSurfType, surf.comment, surf.unit);
     736             :       Print ("PDS-S4", "Value of second fixed surface", Prt_F,
     737             :              sect4->sndSurfValue);
     738             :    }
     739             :    switch (sect4->templat) {
     740             :       case GS4_ANALYSIS:
     741             :       case GS4_ERROR:
     742             :          break;
     743             :       case GS4_ENSEMBLE:
     744             :          Print ("PDS-S4", "Type of Ensemble forecast", Prt_DS,
     745             :                 sect4->typeEnsemble,
     746             :                 Lookup (tbl46, sizeof (tbl46), sect4->typeEnsemble));
     747             :          Print ("PDS-S4", "Perturbation number", Prt_D, sect4->perturbNum);
     748             :          Print ("PDS-S4", "Number of forecasts in ensemble", Prt_D,
     749             :                 sect4->numberFcsts);
     750             :          break;
     751             :       case GS4_ENSEMBLE_STAT:
     752             :          Print ("PDS-S4", "Type of Ensemble forecast", Prt_DS,
     753             :                 sect4->typeEnsemble,
     754             :                 Lookup (tbl46, sizeof (tbl46), sect4->typeEnsemble));
     755             :          Print ("PDS-S4", "Perturbation number", Prt_D, sect4->perturbNum);
     756             :          Print ("PDS-S4", "Number of forecasts in ensemble", Prt_D,
     757             :                 sect4->numberFcsts);
     758             :          Clock_Print (buffer, 100, sect4->validTime, "%m/%d/%Y %H:%M:%S UTC",
     759             :                       0);
     760             :          Print ("PDS-S4", "End of overall time interval", Prt_S, buffer);
     761             :          Print ("PDS-S4", "Total number of missing values", Prt_D,
     762             :                 sect4->numMissing);
     763             :          Print ("PDS-S4", "Number of time range specifications", Prt_D,
     764             :                 sect4->numInterval);
     765             :          for (i = 0; i < sect4->numInterval; i++) {
     766             :             Print ("PDS-S4", "Interval number", Prt_D, i + 1);
     767             :             Print ("PDS-S4", "Statistical process", Prt_DS,
     768             :                    sect4->Interval[i].processID,
     769             :                    Lookup (tbl410, sizeof (tbl410),
     770             :                            sect4->Interval[i].processID));
     771             :             Print ("PDS-S4", "Type of time increment", Prt_DS,
     772             :                    sect4->Interval[i].incrType,
     773             :                    Lookup (tbl411, sizeof (tbl411),
     774             :                            sect4->Interval[i].incrType));
     775             :             /* Following is so we get "# str" not "# (str)" */
     776             :             sprintf (buffer, "%d %s", sect4->Interval[i].lenTime,
     777             :                      Lookup (tbl44, sizeof (tbl44),
     778             :                              sect4->Interval[i].timeRangeUnit));
     779             :             Print ("PDS-S4", "Time range for processing", Prt_S, buffer);
     780             :             /* Following is so we get "# str" not "# (str)" */
     781             :             sprintf (buffer, "%d %s", sect4->Interval[i].timeIncr,
     782             :                      Lookup (tbl44, sizeof (tbl44),
     783             :                              sect4->Interval[i].incrUnit));
     784             :             Print ("PDS-S4", "Time increment", Prt_S, buffer);
     785             :          }
     786             :          break;
     787             :       case GS4_DERIVED:
     788             :          Print ("PDS-S4", "Derived forecast", Prt_DS, sect4->derivedFcst,
     789             :                 Lookup (tbl47, sizeof (tbl47), sect4->derivedFcst));
     790             :          Print ("PDS-S4", "Number of forecasts in ensemble", Prt_D,
     791             :                 sect4->numberFcsts);
     792             :          break;
     793             :       case GS4_DERIVED_INTERVAL:
     794             :          Print ("PDS-S4", "Derived forecast", Prt_DS, sect4->derivedFcst,
     795             :                 Lookup (tbl47, sizeof (tbl47), sect4->derivedFcst));
     796             :          Print ("PDS-S4", "Number of forecasts in ensemble", Prt_D,
     797             :                 sect4->numberFcsts);
     798             :          Clock_Print (buffer, 100, sect4->validTime, "%m/%d/%Y %H:%M:%S UTC",
     799             :                       0);
     800             : 
     801             :          Print ("PDS-S4", "End of overall time interval", Prt_S, buffer);
     802             :          Print ("PDS-S4", "Total number of missing values", Prt_D,
     803             :                 sect4->numMissing);
     804             :          Print ("PDS-S4", "Number of time range specifications", Prt_D,
     805             :                 sect4->numInterval);
     806             :          for (i = 0; i < sect4->numInterval; i++) {
     807             :             Print ("PDS-S4", "Interval number", Prt_D, i + 1);
     808             :             Print ("PDS-S4", "Statistical process", Prt_DS,
     809             :                    sect4->Interval[i].processID,
     810             :                    Lookup (tbl410, sizeof (tbl410),
     811             :                            sect4->Interval[i].processID));
     812             :             Print ("PDS-S4", "Type of time increment", Prt_DS,
     813             :                    sect4->Interval[i].incrType,
     814             :                    Lookup (tbl411, sizeof (tbl411),
     815             :                            sect4->Interval[i].incrType));
     816             :             /* Following is so we get "# str" not "# (str)" */
     817             :             sprintf (buffer, "%d %s", sect4->Interval[i].lenTime,
     818             :                      Lookup (tbl44, sizeof (tbl44),
     819             :                              sect4->Interval[i].timeRangeUnit));
     820             :             Print ("PDS-S4", "Time range for processing", Prt_S, buffer);
     821             :             /* Following is so we get "# str" not "# (str)" */
     822             :             sprintf (buffer, "%d %s", sect4->Interval[i].timeIncr,
     823             :                      Lookup (tbl44, sizeof (tbl44),
     824             :                              sect4->Interval[i].incrUnit));
     825             :             Print ("PDS-S4", "Time increment", Prt_S, buffer);
     826             :          }
     827             :          break;
     828             :       case GS4_PROBABIL_PNT:
     829             :          Print ("PDS-S4", "Forecast Probability Number", Prt_D,
     830             :                 sect4->foreProbNum);
     831             :          Print ("PDS-S4", "Total Number of Forecast Probabilities", Prt_D,
     832             :                 sect4->numForeProbs);
     833             :          Print ("PDS-S4", "Probability type", Prt_DS, sect4->probType,
     834             :                 Lookup (tbl49, sizeof (tbl49), sect4->probType));
     835             :          sprintf (buffer, "%d, %d", sect4->lowerLimit.value,
     836             :                   sect4->lowerLimit.factor);
     837             :          Print ("PDS-S4", "Lower limit (scale value, scale factor)", Prt_GS,
     838             :                 sect4->lowerLimit.value *
     839             :                 pow (10.0, -1 * sect4->lowerLimit.factor), buffer);
     840             :          sprintf (buffer, "%d, %d", sect4->upperLimit.value,
     841             :                   sect4->upperLimit.factor);
     842             :          Print ("PDS-S4", "Upper limit (scale value, scale factor)", Prt_GS,
     843             :                 sect4->upperLimit.value *
     844             :                 pow (10.0, -1 * sect4->upperLimit.factor), buffer);
     845             : /*         printf ("Hello world 1\n");*/
     846             :          break;
     847             :       case GS4_PERCENT_PNT:
     848             :          Print ("PDS-S4", "Percentile", Prt_DS, sect4->percentile, "[%]");
     849             :          break;
     850             :       case GS4_PERCENT_TIME:
     851             :          Print ("PDS-S4", "Percentile", Prt_DS, sect4->percentile, "[%]");
     852             : /*         strftime (buffer, 100, "%m/%d/%Y %H:%M:%S UTC",
     853             :                    gmtime (&(sect4->validTime)));*/
     854             :          Clock_Print (buffer, 100, sect4->validTime, "%m/%d/%Y %H:%M:%S UTC",
     855             :                       0);
     856             : 
     857             :          Print ("PDS-S4", "End of overall time interval", Prt_S, buffer);
     858             :          Print ("PDS-S4", "Total number of missing values", Prt_D,
     859             :                 sect4->numMissing);
     860             :          Print ("PDS-S4", "Number of time range specifications", Prt_D,
     861             :                 sect4->numInterval);
     862             :          for (i = 0; i < sect4->numInterval; i++) {
     863             :             Print ("PDS-S4", "Interval number", Prt_D, i + 1);
     864             :             Print ("PDS-S4", "Statistical process", Prt_DS,
     865             :                    sect4->Interval[i].processID,
     866             :                    Lookup (tbl410, sizeof (tbl410),
     867             :                            sect4->Interval[i].processID));
     868             :             Print ("PDS-S4", "Type of time increment", Prt_DS,
     869             :                    sect4->Interval[i].incrType,
     870             :                    Lookup (tbl411, sizeof (tbl411),
     871             :                            sect4->Interval[i].incrType));
     872             :             /* Following is so we get "# str" not "# (str)" */
     873             :             sprintf (buffer, "%d %s", sect4->Interval[i].lenTime,
     874             :                      Lookup (tbl44, sizeof (tbl44),
     875             :                              sect4->Interval[i].timeRangeUnit));
     876             :             Print ("PDS-S4", "Time range for processing", Prt_S, buffer);
     877             :             /* Following is so we get "# str" not "# (str)" */
     878             :             sprintf (buffer, "%d %s", sect4->Interval[i].timeIncr,
     879             :                      Lookup (tbl44, sizeof (tbl44),
     880             :                              sect4->Interval[i].incrUnit));
     881             :             Print ("PDS-S4", "Time increment", Prt_S, buffer);
     882             :          }
     883             :          break;
     884             :       case GS4_PROBABIL_TIME:
     885             :          Print ("PDS-S4", "Forecast Probability Number", Prt_D,
     886             :                 sect4->foreProbNum);
     887             :          Print ("PDS-S4", "Total Number of Forecast Probabilities", Prt_D,
     888             :                 sect4->numForeProbs);
     889             :          Print ("PDS-S4", "Probability type", Prt_DS, sect4->probType,
     890             :                 Lookup (tbl49, sizeof (tbl49), sect4->probType));
     891             :          sprintf (buffer, "%d, %d", sect4->lowerLimit.value,
     892             :                   sect4->lowerLimit.factor);
     893             :          Print ("PDS-S4", "Lower limit (scale value, scale factor)", Prt_GS,
     894             :                 sect4->lowerLimit.value *
     895             :                 pow (10.0, -1 * sect4->lowerLimit.factor), buffer);
     896             :          sprintf (buffer, "%d, %d", sect4->upperLimit.value,
     897             :                   sect4->upperLimit.factor);
     898             :          Print ("PDS-S4", "Upper limit (scale value, scale factor)", Prt_GS,
     899             :                 sect4->upperLimit.value *
     900             :                 pow (10.0, -1 * sect4->upperLimit.factor), buffer);
     901             :          /* Intentionally fall through. */
     902             :          [[fallthrough]];
     903             :       case GS4_STATISTIC:
     904             : /*         strftime (buffer, 100, "%m/%d/%Y %H:%M:%S UTC",
     905             :                    gmtime (&(sect4->validTime)));*/
     906             :          Clock_Print (buffer, 100, sect4->validTime, "%m/%d/%Y %H:%M:%S UTC",
     907             :                       0);
     908             : 
     909             :          Print ("PDS-S4", "End of overall time interval", Prt_S, buffer);
     910             :          Print ("PDS-S4", "Total number of missing values", Prt_D,
     911             :                 sect4->numMissing);
     912             :          Print ("PDS-S4", "Number of time range specifications", Prt_D,
     913             :                 sect4->numInterval);
     914             :          for (i = 0; i < sect4->numInterval; i++) {
     915             :             Print ("PDS-S4", "Interval number", Prt_D, i + 1);
     916             :             Print ("PDS-S4", "Statistical process", Prt_DS,
     917             :                    sect4->Interval[i].processID,
     918             :                    Lookup (tbl410, sizeof (tbl410),
     919             :                            sect4->Interval[i].processID));
     920             :             Print ("PDS-S4", "Type of time increment", Prt_DS,
     921             :                    sect4->Interval[i].incrType,
     922             :                    Lookup (tbl411, sizeof (tbl411),
     923             :                            sect4->Interval[i].incrType));
     924             :             /* Following is so we get "# str" not "# (str)" */
     925             :             sprintf (buffer, "%d %s", sect4->Interval[i].lenTime,
     926             :                      Lookup (tbl44, sizeof (tbl44),
     927             :                              sect4->Interval[i].timeRangeUnit));
     928             :             Print ("PDS-S4", "Time range for processing", Prt_S, buffer);
     929             :             /* Following is so we get "# str" not "# (str)" */
     930             :             sprintf (buffer, "%d %s", sect4->Interval[i].timeIncr,
     931             :                      Lookup (tbl44, sizeof (tbl44),
     932             :                              sect4->Interval[i].incrUnit));
     933             :             Print ("PDS-S4", "Time increment", Prt_S, buffer);
     934             :          }
     935             :          break;
     936             :       default:
     937             :          /* This case should have been handled in first switch statement of
     938             :           * this procedure, but just in case... */
     939             :          errSprintf ("Un-supported Sect4 template %d\n", sect4->templat);
     940             :          return -2;
     941             :    }
     942             :    return 0;
     943             : }
     944             : 
     945             : /*****************************************************************************
     946             :  * PrintPDS2() --
     947             :  *
     948             :  * Arthur Taylor / MDL
     949             :  *
     950             :  * PURPOSE
     951             :  *   To generate the message for the Product Definition Sections of the GRIB2
     952             :  * Message.
     953             :  *
     954             :  * ARGUMENTS
     955             :  *   meta = The meta file structure to generate the message for. (Input)
     956             :  * f_unit = 0 (GRIB unit), 1 (english), 2 (metric) (Input)
     957             :  *
     958             :  * FILES/DATABASES: None
     959             :  *
     960             :  * RETURNS: void
     961             :  *
     962             :  * HISTORY
     963             :  *   4/2003 Arthur Taylor (MDL/RSIS): Created.
     964             :  *
     965             :  * NOTES
     966             :  *****************************************************************************
     967             :  */
     968             : static int PrintPDS2 (grib_MetaData *meta, sChar f_unit)
     969             : {
     970             :    pdsG2Type *pds2 = &(meta->pds2);
     971             :    /* Based on Grib2 Code Table 0.0 */
     972             :    static const char * const table0[] = {
     973             :       "Meteorological products", "Hydrological products",
     974             :       "Land surface products", "Space products", "Oceanographic products"
     975             :    };
     976             :    int ierr;            /* The error code of a called routine */
     977             : 
     978             :    /* Print the data from Section 0 */
     979             :    switch (pds2->prodType) {
     980             :       case 10:         /* Oceanographic Product. */
     981             :          Print ("PDS-S0", "DataType", Prt_DS, pds2->prodType, table0[4]);
     982             :          break;
     983             :       case 5:          /* Reserved. */
     984             :          Print ("PDS-S0", "DataType", Prt_DS, pds2->prodType,
     985             :                 Lookup (table0, sizeof (table0), 191));
     986             :          break;
     987             :       default:
     988             :          Print ("PDS-S0", "DataType", Prt_DS, pds2->prodType,
     989             :                 Lookup (table0, sizeof (table0), pds2->prodType));
     990             :    }
     991             :    PrintSect1 (pds2, meta->center, meta->subcenter);
     992             :    PrintSect2 (&(pds2->sect2));
     993             :    if ((ierr = PrintSect4 (meta, f_unit)) != 0) {
     994             :       return ierr;
     995             :    }
     996             :    return 0;
     997             : }
     998             : 
     999             : /*****************************************************************************
    1000             :  * PrintPDS1() --
    1001             :  *
    1002             :  * Arthur Taylor / MDL
    1003             :  *
    1004             :  * PURPOSE
    1005             :  *   To generate the message for the Product Definition Sections of the GRIB1
    1006             :  * Message.
    1007             :  *
    1008             :  * ARGUMENTS
    1009             :  *      pds1 = The GRIB1 Product Definition Section to print. (Input)
    1010             :  *   comment = A description about this element. See GRIB1_Table2LookUp (Input)
    1011             :  *    center = The Center that created the data (Input)
    1012             :  * subcenter = The Sub Center that created the data (Input)
    1013             :  *    f_unit = The unit conversion method used on the output data (Input)
    1014             :  *  unitName = The name of the output unit type. (Input)
    1015             :  *   convert = Conversion method used. (Input)
    1016             :  *
    1017             :  * FILES/DATABASES: None
    1018             :  *
    1019             :  * RETURNS: void
    1020             :  *
    1021             :  * HISTORY
    1022             :  *   4/2003 Arthur Taylor (MDL/RSIS): Created.
    1023             :  *  10/2005 AAT: Adjusted to take center, subcenter as we moved that out of
    1024             :  *               the pdsG1 type.
    1025             :  *  11/2005 AAT: Added f_unit variable.
    1026             :  *
    1027             :  * NOTES
    1028             :  *****************************************************************************
    1029             :  */
    1030             : static void PrintPDS1 (pdsG1Type *pds1, char *comment,
    1031             :                        unsigned short int center,
    1032             :                        unsigned short int subcenter, sChar f_unit,
    1033             :                        char *unitName, int convert)
    1034             : {
    1035             :    char buffer[25];     /* Stores format of pds1->refTime. */
    1036             :    const char *ptr;
    1037             : 
    1038             :    Print ("PDS-S1", "Parameter Tables Version", Prt_D, pds1->mstrVersion);
    1039             :    ptr = centerLookup (center);
    1040             :    if (ptr != NULL) {
    1041             :       Print ("PDS-S1", "Originating center", Prt_DS, center, ptr);
    1042             :    } else {
    1043             :       Print ("PDS-S1", "Originating center", Prt_D, center);
    1044             :    }
    1045             :    ptr = subCenterLookup (center, subcenter);
    1046             :    if (ptr != NULL) {
    1047             :       Print ("PDS-S1", "Originating sub-center", Prt_DS, subcenter, ptr);
    1048             :    } else {
    1049             :       Print ("PDS-S1", "Originating sub-center", Prt_D, subcenter);
    1050             :    }
    1051             :    ptr = processLookup (center, pds1->genProcess);
    1052             :    if (ptr != NULL) {
    1053             :       Print ("PDS-S1", "Generation process", Prt_DS, pds1->genProcess, ptr);
    1054             :    } else {
    1055             :       Print ("PDS-S1", "Generation process", Prt_D, pds1->genProcess);
    1056             :    }
    1057             :    Print ("PDS-S1", "Grid Identification Number", Prt_D, pds1->gridID);
    1058             :    Print ("PDS-S1", "Indicator of parameter and units", Prt_DS, pds1->cat,
    1059             :           comment);
    1060             :    if (convert != UC_NONE) {
    1061             :       if (f_unit == 1) {
    1062             :          Print ("PDS-S1", "Output grid, (COMPUTED) english unit is", Prt_S,
    1063             :                 unitName);
    1064             :       } else if (f_unit == 2) {
    1065             :          Print ("PDS-S1", "Output grid, (COMPUTED) metric unit is", Prt_S,
    1066             :                 unitName);
    1067             :       }
    1068             :    }
    1069             :    Print ("PDS-S1", "Type of fixed surface", Prt_D, pds1->levelType);
    1070             :    Print ("PDS-S1", "Value of fixed surface", Prt_D, pds1->levelVal);
    1071             : 
    1072             : /* strftime (buffer, 25, "%m/%d/%Y %H:%M:%S UTC", gmtime (&(pds1->refTime))); */
    1073             :    Clock_Print (buffer, 25, pds1->refTime, "%m/%d/%Y %H:%M:%S UTC", 0);
    1074             : 
    1075             :    Print ("PDS-S1", "Reference Time", Prt_S, buffer);
    1076             : 
    1077             : /* strftime (buffer, 25, "%m/%d/%Y %H:%M:%S UTC",
    1078             :              gmtime (&(pds1->validTime))); */
    1079             :    Clock_Print (buffer, 25, pds1->validTime, "%m/%d/%Y %H:%M:%S UTC", 0);
    1080             : 
    1081             :    Print ("PDS-S1", "Valid Time", Prt_S, buffer);
    1082             : 
    1083             : /* strftime (buffer, 25, "%m/%d/%Y %H:%M:%S UTC", gmtime (&(pds1->P1))); */
    1084             :    Clock_Print (buffer, 25, pds1->P1, "%m/%d/%Y %H:%M:%S UTC", 0);
    1085             : 
    1086             :    Print ("PDS-S1", "P1 Time", Prt_S, buffer);
    1087             : 
    1088             : /* strftime (buffer, 25, "%m/%d/%Y %H:%M:%S UTC", gmtime (&(pds1->P2))); */
    1089             :    Clock_Print (buffer, 25, pds1->P2, "%m/%d/%Y %H:%M:%S UTC", 0);
    1090             : 
    1091             :    Print ("PDS-S1", "P2 Time", Prt_S, buffer);
    1092             :    Print ("PDS-S1", "Time range indicator", Prt_D, pds1->timeRange);
    1093             :    Print ("PDS-S1", "Number included in average", Prt_D, pds1->Average);
    1094             :    Print ("PDS-S1", "Number missing from average or accumulation", Prt_D,
    1095             :           pds1->numberMissing);
    1096             : 
    1097             :    if (pds1->f_hasEns) {
    1098             :       Print ("PDS-S1", "Ensemble BitFlag (octet 29)", Prt_D,
    1099             :              pds1->ens.BitFlag);
    1100             :       Print ("PDS-S1", "Ensemble Application", Prt_D, pds1->ens.Application);
    1101             :       Print ("PDS-S1", "Ensemble Type", Prt_D, pds1->ens.Type);
    1102             :       Print ("PDS-S1", "Ensemble Number", Prt_D, pds1->ens.Number);
    1103             :       Print ("PDS-S1", "Ensemble ProdID", Prt_D, pds1->ens.ProdID);
    1104             :       Print ("PDS-S1", "Ensemble Smoothing", Prt_D, pds1->ens.Smooth);
    1105             :    }
    1106             :    if (pds1->f_hasProb) {
    1107             :       Print ("PDS-S1", "Prob Category", Prt_D, pds1->prob.Cat);
    1108             :       Print ("PDS-S1", "Prob Type", Prt_D, pds1->prob.Type);
    1109             :       Print ("PDS-S1", "Prob lower", Prt_F, pds1->prob.lower);
    1110             :       Print ("PDS-S1", "Prob upper", Prt_F, pds1->prob.upper);
    1111             :    }
    1112             :    if (pds1->f_hasCluster) {
    1113             :       Print ("PDS-S1", "Cluster Ens Size", Prt_D, pds1->cluster.ensSize);
    1114             :       Print ("PDS-S1", "Cluster Size", Prt_D, pds1->cluster.clusterSize);
    1115             :       Print ("PDS-S1", "Cluster Number", Prt_D, pds1->cluster.Num);
    1116             :       Print ("PDS-S1", "Cluster Method", Prt_D, pds1->cluster.Method);
    1117             :       Print ("PDS-S1", "Cluster North Latitude", Prt_F, pds1->cluster.NorLat);
    1118             :       Print ("PDS-S1", "Cluster South Latitude", Prt_F, pds1->cluster.SouLat);
    1119             :       Print ("PDS-S1", "Cluster East Longitude", Prt_F, pds1->cluster.EasLon);
    1120             :       Print ("PDS-S1", "Cluster West Longitude", Prt_F, pds1->cluster.WesLon);
    1121             :       sprintf (buffer, "'%10s'", pds1->cluster.Member);
    1122             :       Print ("PDS-S1", "Cluster Membership", Prt_S, buffer);
    1123             :    }
    1124             : }
    1125             : 
    1126             : /*****************************************************************************
    1127             :  * PrintGDS() --
    1128             :  *
    1129             :  * Arthur Taylor / MDL
    1130             :  *
    1131             :  * PURPOSE
    1132             :  *   To generate the message for the Grid Definition Section.
    1133             :  *
    1134             :  * ARGUMENTS
    1135             :  *     gds = The gds structure to print. (Input)
    1136             :  * version = The GRIB version number (so we know what type of projection) (In)
    1137             :  *
    1138             :  * FILES/DATABASES: None
    1139             :  *
    1140             :  * RETURNS: int (could use errSprintf())
    1141             :  *  0 if no error.
    1142             :  * -1 if asked to print a map projection that we don't support.
    1143             :  *
    1144             :  * HISTORY
    1145             :  *   9/2002 Arthur Taylor (MDL/RSIS): Created.
    1146             :  *   4/2003 AAT: Switched from sect3 to gds
    1147             :  *   5/2003 AAT: Since the number for ProjectionType changed from GRIB1 to
    1148             :  *          GRIB2, we use the GRIB2 internally, but for meta data we want to
    1149             :  *          print the appropriate one.
    1150             :  *   5/2003 AAT: Decided to have 1,1 be lower left corner in .shp files.
    1151             :  *  10/2004 AAT: Added TDLP support.
    1152             :  *
    1153             :  * NOTES
    1154             :  * Need to add support for GS3_ORTHOGRAPHIC = 90,
    1155             :  * GS3_EQUATOR_EQUIDIST = 110, GS3_AZIMUTH_RANGE = 120
    1156             :  *****************************************************************************
    1157             :  */
    1158             : static int PrintGDS (gdsType *gds, int version)
    1159             : {
    1160             :    /* Based on Grib2 Code Table 3.1 */
    1161             :    static const char * const table31[] = { "Latitude/Longitude", "Mercator",
    1162             :       "Polar Stereographic", "Lambert Conformal",
    1163             :       "Space view perspective orthographic",
    1164             :       "Equatorial azimuthal equidistant projection",
    1165             :       "Azimuth-range projection"
    1166             :    };
    1167             :    char buffer[50];     /* Temporary storage for info about scan flag. */
    1168             : 
    1169             :    Print ("GDS", "Number of Points", Prt_D, gds->numPts);
    1170             :    switch (gds->projType) {
    1171             :       case GS3_LATLON: /* 0 */
    1172             :          if (version == 1) {
    1173             :             Print ("GDS", "Projection Type", Prt_DS, GB1S2_LATLON,
    1174             :                    table31[0]);
    1175             :          } else {
    1176             :             Print ("GDS", "Projection Type", Prt_DS, gds->projType,
    1177             :                    table31[0]);
    1178             :          }
    1179             :          break;
    1180             :       case GS3_MERCATOR: /* 10 */
    1181             :          if (version == 1) {
    1182             :             Print ("GDS", "Projection Type", Prt_DS, GB1S2_MERCATOR,
    1183             :                    table31[1]);
    1184             :          } else if (version == -1) {
    1185             :             Print ("GDS", "Projection Type", Prt_DS, TDLP_MERCATOR,
    1186             :                    table31[1]);
    1187             :          } else {
    1188             :             Print ("GDS", "Projection Type", Prt_DS, gds->projType,
    1189             :                    table31[1]);
    1190             :          }
    1191             :          break;
    1192             :       case GS3_POLAR:  /* 20 */
    1193             :          if (version == 1) {
    1194             :             Print ("GDS", "Projection Type", Prt_DS, GB1S2_POLAR, table31[2]);
    1195             :          } else if (version == -1) {
    1196             :             Print ("GDS", "Projection Type", Prt_DS, TDLP_POLAR, table31[2]);
    1197             :          } else {
    1198             :             Print ("GDS", "Projection Type", Prt_DS, gds->projType,
    1199             :                    table31[2]);
    1200             :          }
    1201             :          break;
    1202             :       case GS3_LAMBERT: /* 30 */
    1203             :          if (version == 1) {
    1204             :             Print ("GDS", "Projection Type", Prt_DS, GB1S2_LAMBERT,
    1205             :                    table31[3]);
    1206             :          } else if (version == -1) {
    1207             :             Print ("GDS", "Projection Type", Prt_DS, TDLP_LAMBERT,
    1208             :                    table31[3]);
    1209             :          } else {
    1210             :             Print ("GDS", "Projection Type", Prt_DS, gds->projType,
    1211             :                    table31[3]);
    1212             :          }
    1213             :          break;
    1214             : /*
    1215             :  * The following lines were removed until such time that the rest of this
    1216             :  * procedure can properly handle these three projection types.
    1217             :  *
    1218             :       case GS3_ORTHOGRAPHIC:  * 90 *
    1219             :          Print ("GDS", "Projection Type", Prt_DS, gds->projType, table31[4]);
    1220             :          break;
    1221             :       case GS3_EQUATOR_EQUIDIST:  * 110 *
    1222             :          Print ("GDS", "Projection Type", Prt_DS, gds->projType, table31[5]);
    1223             :          break;
    1224             :       case GS3_AZIMUTH_RANGE:  * 120 *
    1225             :          Print ("GDS", "Projection Type", Prt_DS, gds->projType, table31[6]);
    1226             :          break;
    1227             : */
    1228             :       default:
    1229             :          Print ("GDS", "Projection Type", Prt_D, gds->projType);
    1230             :          errSprintf ("Un-supported Map Projection %d\n", gds->projType);
    1231             :          return -1;
    1232             :    }
    1233             :    if (gds->f_sphere) {
    1234             :       Print ("GDS", "Shape of Earth", Prt_S, "sphere");
    1235             :       Print ("GDS", "Radius", Prt_FS, gds->majEarth, "km");
    1236             :    } else {
    1237             :       Print ("GDS", "Shape of Earth", Prt_S, "oblate spheroid");
    1238             :       Print ("GDS", "semi Major axis", Prt_FS, gds->majEarth, "km");
    1239             :       Print ("GDS", "semi Minor axis", Prt_FS, gds->minEarth, "km");
    1240             :    }
    1241             :    Print ("GDS", "Nx (Number of points on parallel)", Prt_D, gds->Nx);
    1242             :    Print ("GDS", "Ny (Number of points on meridian)", Prt_D, gds->Ny);
    1243             :    Print ("GDS", "Lat1", Prt_F, gds->lat1);
    1244             :    Print ("GDS", "Lon1", Prt_F, gds->lon1);
    1245             :    if (gds->resFlag & GRIB2BIT_5) {
    1246             :       Print ("GDS", "u/v vectors relative to", Prt_S, "grid");
    1247             :    } else {
    1248             :       Print ("GDS", "u/v vectors relative to", Prt_S, "easterly/northerly");
    1249             :    }
    1250             :    if (gds->projType == GS3_LATLON) {
    1251             :       Print ("GDS", "Lat2", Prt_F, gds->lat2);
    1252             :       Print ("GDS", "Lon2", Prt_F, gds->lon2);
    1253             :       Print ("GDS", "Dx", Prt_FS, gds->Dx, "degrees");
    1254             :       Print ("GDS", "Dy", Prt_FS, gds->Dy, "degrees");
    1255             :    } else if (gds->projType == GS3_MERCATOR) {
    1256             :       Print ("GDS", "Lat2", Prt_F, gds->lat2);
    1257             :       Print ("GDS", "Lon2", Prt_F, gds->lon2);
    1258             :       Print ("GDS", "Dx", Prt_FS, gds->Dx, "m");
    1259             :       Print ("GDS", "Dy", Prt_FS, gds->Dy, "m");
    1260             :    } else if ((gds->projType == GS3_POLAR)
    1261             :               || (gds->projType == GS3_LAMBERT)) {
    1262             :       Print ("GDS", "Dx", Prt_FS, gds->Dx, "m");
    1263             :       Print ("GDS", "Dy", Prt_FS, gds->Dy, "m");
    1264             :    }
    1265             :    /* For scan mode... The user of this data doesn't necessarily care how it
    1266             :     * was stored in the Grib2 grid (i.e. gds->scan), they just care about how
    1267             :     * the data they are accessing is scanned (i.e. scan=0000) */
    1268             :    sprintf (buffer, "%d%d%d%d", ((gds->scan & GRIB2BIT_1) / GRIB2BIT_1),
    1269             :             ((gds->scan & GRIB2BIT_2) / GRIB2BIT_2),
    1270             :             ((gds->scan & GRIB2BIT_3) / GRIB2BIT_3),
    1271             :             ((gds->scan & GRIB2BIT_4) / GRIB2BIT_4));
    1272             :    Print ("GDS", "Input GRIB2 grid, scan mode", Prt_DS, gds->scan, buffer);
    1273             : /*
    1274             :    Print ("GDS", "Output grid, scan mode", Prt_DS, 0, "0000");
    1275             :    Print ("GDS", "Output grid, scan i/x direction", Prt_S, "positive");
    1276             :    Print ("GDS", "Output grid, scan j/y direction", Prt_S, "negative");
    1277             : */
    1278             :    Print ("GDS", "Output grid, scan mode", Prt_DS, 64, "0100");
    1279             :    Print ("GDS", "(.flt file grid), scan mode", Prt_DS, 0, "0000");
    1280             :    Print ("GDS", "Output grid, scan i/x direction", Prt_S, "positive");
    1281             :    Print ("GDS", "Output grid, scan j/y direction", Prt_S, "positive");
    1282             :    Print ("GDS", "(.flt file grid), scan j/y direction", Prt_S, "negative");
    1283             :    Print ("GDS", "Output grid, consecutive points in", Prt_S,
    1284             :           "i/x direction");
    1285             :    Print ("GDS", "Output grid, adjacent rows scan in", Prt_S,
    1286             :           "same direction");
    1287             : 
    1288             :    /* Meshlat/orient lon/scale lat have no meaning for lat/lon grids. */
    1289             :    if (gds->projType != GS3_LATLON) {
    1290             :       Print ("GDS", "MeshLat", Prt_F, gds->meshLat);
    1291             :       Print ("GDS", "OrientLon", Prt_F, gds->orientLon);
    1292             :       if ((gds->projType == GS3_POLAR) || (gds->projType == GS3_LAMBERT)) {
    1293             :          if (gds->center & GRIB2BIT_1) {
    1294             :             Print ("GDS", "Which pole is on the plane", Prt_S, "South");
    1295             :          } else {
    1296             :             Print ("GDS", "Which pole is on the plane", Prt_S, "North");
    1297             :          }
    1298             :          if (gds->center & GRIB2BIT_2) {
    1299             :             Print ("GDS", "bi-polar projection", Prt_S, "Yes");
    1300             :          } else {
    1301             :             Print ("GDS", "bi-polar projection", Prt_S, "No");
    1302             :          }
    1303             :       }
    1304             :       Print ("GDS", "Tangent Lat1", Prt_F, gds->scaleLat1);
    1305             :       Print ("GDS", "Tangent Lat2", Prt_F, gds->scaleLat2);
    1306             :       Print ("GDS", "Southern Lat", Prt_F, gds->southLat);
    1307             :       Print ("GDS", "Southern Lon", Prt_F, gds->southLon);
    1308             :    }
    1309             :    return 0;
    1310             : }
    1311             : 
    1312             : /*****************************************************************************
    1313             :  * PrintGridAttrib() --
    1314             :  *
    1315             :  * Arthur Taylor / MDL
    1316             :  *
    1317             :  * PURPOSE
    1318             :  *   To generate the message for the various attributes of the grid.
    1319             :  *
    1320             :  * ARGUMENTS
    1321             :  *  attrib = The Grid Attribute structure to print. (Input)
    1322             :  * decimal = How many decimals to round to. (Input)
    1323             :  *
    1324             :  * FILES/DATABASES: None
    1325             :  *
    1326             :  * RETURNS: void
    1327             :  *
    1328             :  * HISTORY
    1329             :  *   9/2002 Arthur Taylor (MDL/RSIS): Created.
    1330             :  *   5/2003 AAT: Added rounding to decimal.
    1331             :  *
    1332             :  * NOTES
    1333             :  *****************************************************************************
    1334             :  */
    1335             : static void PrintGridAttrib (gridAttribType *attrib, sChar decimal)
    1336             : {
    1337             :    /* Based on Grib2 Code Table 5.0 */
    1338             :    static const char * const table50[] = {
    1339             :       "Grid point data - simple packing", "Matrix value - simple packing",
    1340             :       "Grid point data - complex packing",
    1341             :       "Grid point data - complex packing and spatial differencing"
    1342             :    };
    1343             : 
    1344             :    /* Based on Grib2 Code Table 5.1 */
    1345             :    static const char * const table51[] = { "Floating point", "Integer" };
    1346             : 
    1347             :    /* Based on Grib2 Code Table 5.5 */
    1348             :    static const char * const table55[] = {
    1349             :       "No explicit missing value included with data",
    1350             :       "Primary missing value included with data",
    1351             :       "Primary and Secondary missing values included with data"
    1352             :    };
    1353             : 
    1354             :    if ((attrib->packType == GS5_JPEG2000) ||
    1355             :        (attrib->packType == GS5_JPEG2000_ORG)) {
    1356             :       Print ("Info", "Packing that was used", Prt_DS, attrib->packType,
    1357             :              "JPEG 2000");
    1358             :    } else if ((attrib->packType == GS5_PNG) ||
    1359             :               (attrib->packType == GS5_PNG_ORG)) {
    1360             :       Print ("Info", "Packing that was used", Prt_DS, attrib->packType,
    1361             :              "Portable Network Graphics (PNG)");
    1362             :    } else {
    1363             :       Print ("Info", "Packing that was used", Prt_DS, attrib->packType,
    1364             :              Lookup (table50, sizeof (table50), attrib->packType));
    1365             :    }
    1366             :    /* Added next two 1/27/2006 because of questions from Val. */
    1367             :    Print ("Info", "Decimal Scale Factor", Prt_D, attrib->DSF);
    1368             :    Print ("Info", "Binary Scale Factor", Prt_D, attrib->ESF);
    1369             :    Print ("Info", "Original field type", Prt_DS, attrib->fieldType,
    1370             :           Lookup (table51, sizeof (table51), attrib->fieldType));
    1371             :    Print ("Info", "Missing value management", Prt_DS, attrib->f_miss,
    1372             :           Lookup (table55, sizeof (table55), attrib->f_miss));
    1373             :    if (attrib->f_miss == 1) {
    1374             :       Print ("Info", "Primary missing value", Prt_F,
    1375             :              myRound (attrib->missPri, decimal));
    1376             :    } else if (attrib->f_miss == 2) {
    1377             :       Print ("Info", "Primary missing value", Prt_F,
    1378             :              myRound (attrib->missPri, decimal));
    1379             :       Print ("Info", "Secondary missing value", Prt_F,
    1380             :              myRound (attrib->missSec, decimal));
    1381             :    }
    1382             :    Print ("Info", "Detected number of Missing", Prt_D, attrib->numMiss);
    1383             :    if (attrib->f_maxmin) {
    1384             :       Print ("Info", "Field minimum value", Prt_F,
    1385             :              myRound (attrib->min, decimal));
    1386             :       Print ("Info", "Field maximum value", Prt_F,
    1387             :              myRound (attrib->max, decimal));
    1388             :    }
    1389             : }
    1390             : 
    1391             : /*****************************************************************************
    1392             :  * MetaPrintGDS() --
    1393             :  *
    1394             :  * Arthur Taylor / MDL
    1395             :  *
    1396             :  * PURPOSE
    1397             :  *   To generate a message specific for the GDS.  Basically a wrapper for
    1398             :  * PrintGDS and Print.
    1399             :  *
    1400             :  * ARGUMENTS
    1401             :  * gds = The Grid Definition Section to generate the message for. (Input)
    1402             :  * version = The GRIB version number (so we know what type of projection) (In)
    1403             :  * ans = The resulting message. Up to caller to free. (Output)
    1404             :  *
    1405             :  * FILES/DATABASES: None
    1406             :  *
    1407             :  * RETURNS: int (could use errSprintf())
    1408             :  *  0 if no error.
    1409             :  * -1 if asked to print a map projection that we don't support.
    1410             :  * -2 if asked to print data for a template that we don't support.
    1411             :  *
    1412             :  * HISTORY
    1413             :  *   4/2003 Arthur Taylor (MDL/RSIS): Created.
    1414             :  *   5/2003 AAT: Commented out.  Purpose was mainly for debugging degrib1.c,
    1415             :  *               which is now working.
    1416             :  *
    1417             :  * NOTES
    1418             :  *****************************************************************************
    1419             :  */
    1420             : int MetaPrintGDS (gdsType *gds, int version, char **ans)
    1421             : {
    1422             :    int ierr;            /* The error code of a called routine */
    1423             : 
    1424             :    if ((ierr = PrintGDS (gds, version)) != 0) {
    1425             :       *ans = Print (NULL, NULL, Prt_NULL);
    1426             :       preErrSprintf ("Print error Section 3\n");
    1427             :       return ierr;
    1428             :    }
    1429             :    *ans = Print (NULL, NULL, Prt_NULL);
    1430             :    return 0;
    1431             : }
    1432             : 
    1433             : /*****************************************************************************
    1434             :  * MetaPrint() --
    1435             :  *
    1436             :  * Arthur Taylor / MDL
    1437             :  *
    1438             :  * PURPOSE
    1439             :  *   To generate the meta file message.
    1440             :  *
    1441             :  * ARGUMENTS
    1442             :  *    meta = The meta file structure to generate the message for. (Input)
    1443             :  *     ans = The resulting message. Up to caller to free. (Output)
    1444             :  * decimal = How many decimals to round to. (Input)
    1445             :  *  f_unit = 0 (GRIB unit), 1 (english), 2 (metric) (Input)
    1446             :  *
    1447             :  * FILES/DATABASES: None
    1448             :  *
    1449             :  * RETURNS: int (could use errSprintf())
    1450             :  *  0 if no error.
    1451             :  * -1 if asked to print a map projection that we don't support.
    1452             :  * -2 if asked to print data for a template that we don't support.
    1453             :  *
    1454             :  * HISTORY
    1455             :  *   9/2002 Arthur Taylor (MDL/RSIS): Created.
    1456             :  *   5/2003 AAT: Added rounding to decimal.
    1457             :  *
    1458             :  * NOTES
    1459             :  *****************************************************************************
    1460             :  */
    1461             : int MetaPrint (grib_MetaData *meta, char **ans, sChar decimal, sChar f_unit)
    1462             : {
    1463             :    int ierr;            /* The error code of a called routine */
    1464             : 
    1465             :    if (meta->GribVersion == 1) {
    1466             :       PrintPDS1 (&(meta->pds1), meta->comment, meta->center,
    1467             :                  meta->subcenter, f_unit, meta->unitName, meta->convert);
    1468             :    } else if (meta->GribVersion == -1) {
    1469             :       PrintPDS_TDLP (&(meta->pdsTdlp));
    1470             :    } else {
    1471             :       if ((ierr = PrintPDS2 (meta, f_unit)) != 0) {
    1472             :          *ans = Print (NULL, NULL, Prt_NULL);
    1473             :          preErrSprintf ("Print error in PDS for GRIB2\n");
    1474             :          return ierr;
    1475             :       }
    1476             :    }
    1477             :    if ((ierr = PrintGDS (&(meta->gds), meta->GribVersion)) != 0) {
    1478             :       *ans = Print (NULL, NULL, Prt_NULL);
    1479             :       preErrSprintf ("Print error Section 3\n");
    1480             :       return ierr;
    1481             :    }
    1482             :    PrintGridAttrib (&(meta->gridAttrib), decimal);
    1483             :    *ans = Print (NULL, NULL, Prt_NULL);
    1484             :    return 0;
    1485             : }
    1486             : #endif  // Unused with GDAL.

Generated by: LCOV version 1.14