LCOV - code coverage report
Current view: directory - frmts/grib/degrib18/degrib - metaprint.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 463 0 0.0 %
Date: 2010-01-09 Functions: 12 0 0.0 %

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

Generated by: LCOV version 1.7