apisample.c

Go to the documentation of this file.
00001 /*------------------------------------------------------------------------
00002 
00003     BUFR encoding and decoding software and library
00004     Copyright (c) 2007,  Institute of Broadband Communication, TU-Graz
00005     on behalf of EUMETNET OPERA, http://www.knmi.nl/opera
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; version 2.1 
00010     of the License.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
00020 
00021 ----------------------------------------------------------------------------
00022 
00023 FILE:          APISAMPLE.C
00024 IDENT:         $Id: apisample.c,v 1.2 2007/12/18 14:40:13 fuxi Exp $
00025 
00026 AUTHOR:        Juergen Fuchsberger
00027                Institute of Broadband Communication, 
00028                Technical University Graz, Austria
00029 
00030 VERSION NUMBER:3.0
00031 
00032 DATE CREATED:  4-DEC-2007
00033 
00034 STATUS:        DEVELOPMENT FINISHED
00035 
00036 AMENDMENT RECORD:
00037 
00038 $Log: apisample.c,v $
00039 Revision 1.2  2007/12/18 14:40:13  fuxi
00040 added licence header
00041 
00042 Revision 1.1  2007/12/07 08:37:16  fuxi
00043 Initial revision
00044 
00045 
00046 --------------------------------------------------------------------------- */
00047 
00056 #include <stdlib.h>
00057 #include <stdio.h>
00058 #include <string.h>
00059 #include <assert.h>
00060 #include "bufrlib.h"
00061 #include "apisample.h"
00062 #include "bufr_io.h"
00063 
00064 /*===========================================================================*/
00065 /* internal function definitons                                              */
00066 /*===========================================================================*/
00067 
00068 static void create_source_msg (dd* descs, int* nd, varfl** vals, 
00069                                radar_data_t* d);
00070 static int our_callback (varfl val, int ind);
00071 static void create_sample_data (radar_data_t* d);
00072 
00073 /*===========================================================================*/
00074 /* internal data                                                             */
00075 /*===========================================================================*/
00076 
00077 radar_data_t our_data; /* sturcture holding our decoded data */
00078 char *version = "apisample V3.0, 5-Dec-2007\n";
00079 
00080 /*===========================================================================*/
00081 
00095 void bufr_encoding_sample (radar_data_t* src_data, bufr_t* bufr_msg) {
00096 
00097     sect_1_t s1;          /* structure holding information from section 1 */
00098     dd descs[MAX_DESCS];  /* array of data descriptors, must be large enough
00099                              to hold all required descriptors */
00100     int nd = 0;           /* current number of descriptors in descs */
00101     varfl* vals = NULL;   /* array of data values */
00102     int ok;
00103 
00104     long year, mon, day, hour, min;
00105 
00106     memset (&s1, 0, sizeof (sect_1_t));
00107     
00108     /* first let's create our source message */
00109 
00110     create_source_msg (descs, &nd, &vals, src_data);
00111 
00112     /* Prepare data for section 1 */
00113 
00114     s1.year = 999;
00115     s1.mon  = 999;
00116     s1.day = 999;
00117     s1.hour = 999;
00118     s1.min  = 999;
00119     s1.mtab = 0;                      /* master table used */
00120     s1.subcent = 255;                 /* originating subcenter */
00121     s1.gencent = 255;                 /* originating center */
00122     s1.updsequ = 0;                   /* original BUFR message */
00123     s1.opsec = 0;                     /* no optional section */
00124     s1.dcat = 6;                      /* message type */
00125     s1.dcatst = 0;                    /* message subtype */
00126     s1.vmtab = 11;                    /* version number of master table used */
00127     s1.vltab = 4;                     /* version number of local table used */
00128 
00129     /* read supported data descriptors from tables */
00130 
00131     ok = (read_tables (NULL, s1.vmtab, s1.vltab, s1.subcent, s1.gencent) >= 0);
00132 
00133     /* encode our data to a data-descriptor- and data-section */
00134 
00135     if (ok) ok = bufr_encode_sections34 (descs, nd, vals, bufr_msg);
00136 
00137     /* setup date and time if necessary */
00138 
00139     if (ok && s1.year == 999) {
00140         bufr_get_date_time (&year, &mon, &day, &hour, &min);
00141         s1.year = (int) year;
00142         s1.mon = (int) mon;
00143         s1.day = (int) day;
00144         s1.hour = (int) hour;
00145         s1.min = (int) min;
00146         s1.sec = 0;
00147     }
00148 
00149     /* encode section 0, 1, 2, 5 */
00150 
00151     if (ok) ok = bufr_encode_sections0125 (&s1, bufr_msg);
00152 
00153     /* Save coded data */
00154 
00155     if (ok) ok = bufr_write_file (bufr_msg, "apisample.bfr");
00156 
00157     if (vals != NULL)
00158         free (vals);
00159     free_descs ();
00160 
00161     if (!ok) exit (EXIT_FAILURE);
00162 }
00163 
00164 /*===========================================================================*/
00177 void bufr_decoding_sample (bufr_t* msg, radar_data_t* data) {
00178 
00179     sect_1_t s1;
00180     int ok, desch, ndescs;
00181     dd* dds = NULL;
00182 
00183     /* initialize variables */
00184 
00185     memset (&s1, 0, sizeof (sect_1_t));
00186 
00187     /* Here we could also read our BUFR message from a file */
00188     /* bufr_read_file (msg, buffile); */
00189 
00190     /* decode section 1 */
00191 
00192     ok = bufr_decode_sections01 (&s1, msg);
00193 
00194     /* Write section 1 to ASCII file */
00195 
00196     bufr_sect_1_to_file (&s1, "section.1.out");
00197 
00198     /* read descriptor tables */
00199 
00200     if (ok) ok = (read_tables (NULL, s1.vmtab, s1.vltab, s1.subcent, 
00201                                s1.gencent) >= 0);
00202 
00203     /* decode data descriptor and data-section now */
00204 
00205     /* open bitstreams for section 3 and 4 */
00206 
00207     desch = bufr_open_descsec_r(msg);
00208     ok = (desch >= 0);
00209     if (ok) ok = (bufr_open_datasect_r(msg) >= 0);
00210 
00211     /* calculate number of data descriptors  */
00212     
00213     ndescs = bufr_get_ndescs (msg);
00214 
00215     /* allocate memory and read data descriptors from bitstream */
00216 
00217     if (ok) ok = bufr_in_descsec (&dds, ndescs, desch);
00218 
00219     /* output data to our global data structure */
00220 
00221     if (ok) ok = bufr_parse_out (dds, 0, ndescs - 1, our_callback, 1);
00222 
00223     /* get data from global */
00224 
00225     data = &our_data;
00226 
00227     /* close bitstreams and free descriptor array */
00228 
00229     if (dds != (dd*) NULL)
00230         free (dds);
00231     bufr_close_descsec_r (desch);
00232     bufr_close_datasect_r ();
00233 
00234     /* decode data to file also */
00235 
00236     if (ok) ok = bufr_data_to_file ("apisample.src", "apisample.img", msg);
00237 
00238     bufr_free_data (msg);
00239     free_descs();
00240     exit (EXIT_SUCCESS);
00241 
00242 
00243 }
00244 
00245 /*===========================================================================*/
00246 /* 
00247 Sample for encoding and decoding a BUFR message 
00248 
00249 */
00250 
00251 int main (int argc, char* argv[]) {
00252 
00253     bufr_t bufr_msg ;   /* structure holding encoded bufr message */
00254 
00255     /* initialize variables */
00256 
00257     memset (&bufr_msg, 0, sizeof (bufr_t));
00258     memset (&our_data, 0, sizeof (radar_data_t));
00259 
00260     /* check command line parameters */
00261 
00262     while (argc > 1 && *argv[1] == '-')
00263     {
00264         if (*(argv[1] + 1) == 'v')
00265             fprintf (stderr, "%s", version);
00266     }
00267 
00268     /* sample for encoding to BUFR */
00269 
00270     create_sample_data (&our_data);
00271     bufr_encoding_sample (&our_data, &bufr_msg);
00272 
00273     /* sample for decoding from BUFR */
00274 
00275     memset (&our_data, 0, sizeof (radar_data_t));
00276     bufr_decoding_sample (&bufr_msg, &our_data);
00277     bufr_free_data (&bufr_msg);
00278 
00279     free (our_data.img.data);
00280 
00281     exit (EXIT_SUCCESS);
00282 }
00283 
00284 
00285 /*===========================================================================*/
00286 #define fill_desc(ff,xx,yy) {\
00287         dd.f=ff; dd.x=xx; dd.y=yy; \
00288         bufr_desc_to_array (descs, dd, nd);}
00289 #define fill_v(val) bufr_val_to_array (vals, val, &nv);
00290 
00294 static void create_source_msg (dd* descs, int* nd, varfl** vals, 
00295                                radar_data_t* d) {
00296 
00297     dd dd;
00298     int nv = 0, i;
00299 
00300     fill_desc(3,1,1);           /* WMO block and station number */
00301     fill_v(d->wmoblock);
00302     fill_v(d->wmostat);
00303 
00304     fill_desc(3,1,192);         /* Meta information about the product */
00305     fill_v(d->meta.year);       /* Date */
00306     fill_v(d->meta.month);
00307     fill_v(d->meta.day);
00308     fill_v(d->meta.hour);       /* Time */
00309     fill_v(d->meta.min);
00310     fill_v(d->img.nw.lat);      /* Lat. / lon. of NW corner */
00311     fill_v(d->img.nw.lon);
00312     fill_v(d->img.ne.lat);      /* Lat. / lon. of NE corner */
00313     fill_v(d->img.ne.lon);
00314     fill_v(d->img.se.lat);      /* Lat. / lon. of SE corner */
00315     fill_v(d->img.se.lon);
00316     fill_v(d->img.sw.lat);      /* Lat. / lon. of SW corner */
00317     fill_v(d->img.sw.lon);
00318     fill_v(d->proj.type);             /* Projection type */
00319     fill_v(d->meta.radar.lat);        /* Latitude of radar */
00320     fill_v(d->meta.radar.lon);        /* Longitude of radar */
00321     fill_v(d->img.psizex);            /* Pixel size along x coordinate */
00322     fill_v(d->img.psizey);            /* Pixel size along y coordinate */
00323     fill_v(d->img.nrows);             /* Number of pixels per row */
00324     fill_v(d->img.ncols);             /* Number of pixels per column */
00325 
00326     fill_desc(3,1,22);          /* Latitude, longitude and height of station */
00327     fill_v(d->meta.radar.lat);
00328     fill_v(d->meta.radar.lon);
00329     fill_v(d->meta.radar_height);
00330 
00331                                 /* Projection information (this will be 
00332                                    a sequence descriptor when using tables 6 */
00333     fill_desc(0,29,199);        /* Semi-major axis or rotation ellipsoid */
00334     fill_v(d->proj.majax);
00335     fill_desc(0,29,200);        /* Semi-minor axis or rotation ellipsoid */
00336     fill_v(d->proj.minax);
00337     fill_desc(0,29,193);        /* Longitude Origin */
00338     fill_v(d->proj.orig.lon);
00339     fill_desc(0,29,194);        /* Latitude Origin */
00340     fill_v(d->proj.orig.lat);
00341     fill_desc(0,29,195);        /* False Easting */
00342     fill_v(d->proj.xoff);
00343     fill_desc(0,29,196);        /* False Northing */
00344     fill_v(d->proj.yoff);
00345     fill_desc(0,29,197);        /* 1st Standard Parallel */
00346     fill_v(d->proj.stdpar1);
00347     fill_desc(0,29,198);        /* 2nd Standard Parallel */
00348     fill_v(d->proj.stdpar2);
00349 
00350     fill_desc(0,30,31);         /* Image type */
00351     fill_v(d->img.type);
00352 
00353     fill_desc(0,29,2);          /* Co-ordinate grid */
00354     fill_v(d->img.grid);
00355 
00356     fill_desc(0,33,3);          /* Quality information */
00357     fill_v(d->img.qual);
00358 
00359 
00360     /* level slicing table note the use of change of datawith in order to 
00361        encode our values, also values are converted to integer, loosing
00362        precision
00363     */
00364 
00365     fill_desc(2,1,129);          /* change of datawidth because 0 21 1 
00366                                     only codes to 7 bit */
00367     fill_desc(3,13,9);          /* Reflectivity scale */
00368     fill_v(d->img.scale.vals[0]);   /* scale[0] */
00369     fill_v(d->img.scale.nvals -1);     /* number of scale values - 1 */ 
00370     for (i = 1; i < d->img.scale.nvals; i++) {
00371         fill_v(d->img.scale.vals[i]);
00372     }
00373     fill_desc(2,1,0);          /* cancel change of datawidth */
00374 
00375     /* another possibility for the level slicing table withour using
00376        datawidth and scale change and without loosing precision */
00377 
00378     fill_desc(0,21,198);        /* dBZ Value offset */
00379     fill_v(d->img.scale.offset);
00380     fill_desc(0,21,199);        /* dBZ Value increment */
00381     fill_v(d->img.scale.increment);
00382 
00383 
00384     fill_desc(3,21,193);        /* 8 bit per pixel pixmap */
00385 
00386     /* run length encode our bitmap */
00387     rlenc_from_mem (d->img.data, d->img.nrows, d->img.ncols, vals, &nv);
00388     
00389     free(d->img.data);
00390 }
00391 
00392 /*===========================================================================*/
00393 
00398 static int our_callback (varfl val, int ind) {
00399 
00400     radar_data_t* b = &our_data;   /* our global data structure */
00401     bufrval_t* v;                  /* array of data values */
00402     varfl* vv;
00403     int i = 0, nv, nr, nc;
00404     dd* d;
00405 
00406     /* do nothing if data modifictaon descriptor or replication descriptor */
00407 
00408     if (ind == _desc_special) return 1;
00409 
00410     /* sequence descriptor */
00411 
00412     if (des[ind]->id == SEQDESC) {
00413 
00414         /* get descriptor */
00415 
00416         d = &(des[ind]->seq->d);
00417 
00418         /* open array for values */
00419 
00420         v = bufr_open_val_array ();
00421         if (v == (bufrval_t*) NULL) return 0;
00422 
00423         /* WMO block and station number */
00424 
00425         if  (bufr_check_fxy (d, 3,1,1)) {   
00426 
00427             /* decode sequence to global array */
00428 
00429             bufr_parse_out (des[ind]->seq->del, 0, des[ind]->seq->nel - 1,
00430                             bufr_val_to_global, 0);
00431 
00432             /* get our data from the array */
00433 
00434             b->wmoblock = (int) v->vals[i++];
00435             b->wmostat = (int) v->vals[i];
00436 
00437         }
00438         /* Meta information */
00439 
00440         else if (bufr_check_fxy (d, 3,1,192)) { 
00441 
00442             bufr_parse_out (des[ind]->seq->del, 0, des[ind]->seq->nel - 1,
00443                             bufr_val_to_global, 0);
00444             vv = v->vals;
00445             i = 0;
00446             b->meta.year = (int) vv[i++];       /* Date */
00447             b->meta.month = (int) vv[i++];
00448             b->meta.day = (int) vv[i++];
00449             b->meta.hour = (int) vv[i++];       /* Time */
00450             b->meta.min = (int) vv[i++];
00451             b->img.nw.lat = vv[i++];      /* Lat. / lon. of NW corner */
00452             b->img.nw.lon = vv[i++];
00453             b->img.ne.lat = vv[i++];      /* Lat. / lon. of NE corner */
00454             b->img.ne.lon = vv[i++];
00455             b->img.se.lat = vv[i++];      /* Lat. / lon. of SE corner */
00456             b->img.se.lon = vv[i++];
00457             b->img.sw.lat = vv[i++];      /* Lat. / lon. of SW corner */
00458             b->img.sw.lon = vv[i++];
00459             b->proj.type = (int) vv[i++];       /* Projection type */
00460             b->meta.radar.lat = vv[i++];        /* Latitude of radar */
00461             b->meta.radar.lon = vv[i++];        /* Longitude of radar */
00462             b->img.psizex = vv[i++];      /* Pixel size along x coordinate */
00463             b->img.psizey = vv[i++];      /* Pixel size along y coordinate */
00464             b->img.nrows = (int) vv[i++];     /* Number of pixels per row */
00465             b->img.ncols = (int) vv[i++];     /* Number of pixels per column */
00466 
00467         }
00468         /* Latitude, longitude and height of station */
00469 
00470         else if (bufr_check_fxy (d, 3,1,22)) { 
00471 
00472             bufr_parse_out (des[ind]->seq->del, 0, des[ind]->seq->nel - 1,
00473                             bufr_val_to_global, 0);
00474             vv = v->vals;
00475             i = 0;
00476             b->meta.radar.lat = vv[i++];
00477             b->meta.radar.lon = vv[i++];
00478             b->meta.radar_height = vv[i];
00479         }
00480         /* Reflectivity scale */
00481 
00482         else if (bufr_check_fxy (d, 3,13,9)) { 
00483             int j;
00484 
00485             bufr_parse_out (des[ind]->seq->del, 0, des[ind]->seq->nel - 1,
00486                             bufr_val_to_global, 0);
00487             vv = v->vals;
00488             i = 0;
00489             
00490             b->img.scale.vals[0] = vv[i++];
00491             b->img.scale.nvals = (int) vv[i++] + 1;  /* number of scale values */ 
00492             assert(b->img.scale.nvals < 256);
00493             for (j = 1; j < b->img.scale.nvals; j++) {
00494                 b->img.scale.vals[j] = vv[i++];
00495             }
00496         }
00497 
00498         /* our bitmap */
00499 
00500         else if (bufr_check_fxy (d, 3,21,193)) {
00501 
00502             /* read bitmap and run length decode */
00503 
00504             if (!bufr_parse_out (des[ind]->seq->del, 0, des[ind]->seq->nel - 1,
00505                                  bufr_val_to_global, 0)) {
00506                 bufr_close_val_array ();
00507                 return 0;
00508             }
00509 
00510             if (!rldec_to_mem (v->vals, &(b->img.data), &nv, &nr, &nc)) { 
00511                 bufr_close_val_array ();
00512                 fprintf (stderr, "Error during runlength-compression.\n");
00513                 return 0;
00514             }
00515         }
00516      
00517         else {
00518             fprintf (stderr,
00519                      "Unknown sequence descriptor %d %d %d", d->f, d->x, d->y);
00520         }
00521         /* close the global value array */
00522 
00523         bufr_close_val_array ();
00524 
00525     }
00526 
00527     /* element descriptor */
00528 
00529     else if (des[ind]->id == ELDESC) {
00530 
00531         d = &(des[ind]->el->d);
00532 
00533         if (bufr_check_fxy (d, 0,29,199))
00534             /* Semi-major axis or rotation ellipsoid */
00535             b->proj.majax = val;
00536         else if (bufr_check_fxy (d, 0,29,200))
00537             /* Semi-minor axis or rotation ellipsoid */
00538             b->proj.minax = val;
00539         else if (bufr_check_fxy (d, 0,29,193))
00540             /* Longitude Origin */
00541             b->proj.orig.lon = val;
00542         else if (bufr_check_fxy (d, 0,29,194))
00543             /* Latitude Origin */
00544             b->proj.orig.lat = val;
00545         else if (bufr_check_fxy (d, 0,29,195))
00546             /* False Easting */
00547             b->proj.xoff = (int) val;
00548         else if (bufr_check_fxy (d, 0,29,196))
00549             /* False Northing */
00550             b->proj.yoff = (int) val;
00551         else if (bufr_check_fxy (d, 0,29,197))
00552             /* 1st Standard Parallel */
00553             b->proj.stdpar1 = val;
00554         else if (bufr_check_fxy (d, 0,29,198))
00555             /* 2nd Standard Parallel */
00556             b->proj.stdpar2 = val;
00557         else if (bufr_check_fxy (d, 0,30,31))
00558             /* Image type */
00559             b->img.type = (int) val;
00560         else if (bufr_check_fxy (d, 0,29,2))
00561             /* Co-ordinate grid */
00562             b->img.grid = (int) val;
00563         else if (bufr_check_fxy (d, 0,33,3))
00564             /* Quality information */
00565             b->img.qual = val;
00566         else if (bufr_check_fxy (d, 0,21,198))
00567             /* dBZ Value offset */
00568             b->img.scale.offset = val;
00569         else if (bufr_check_fxy (d, 0,21,199))
00570             /* dBZ Value increment */
00571             b->img.scale.increment = val;
00572         else {
00573             fprintf (stderr,
00574                      "Unknown element descriptor %d %d %d", d->f, d->x, d->y);
00575             return 0;
00576         }
00577     }
00578     return 1;
00579 }
00580 
00581 /*===========================================================================*/
00582 #define NROWS 200   /* Number of rows for our sample radar image */
00583 #define NCOLS 200   /* Number of columns for our sample radar image */
00584 
00585 static void create_sample_data (radar_data_t* d) {
00586 
00587     int i;
00588 
00589     /* create a sample radar image */
00590     
00591     d->img.data = (unsigned short*) calloc (NROWS * NCOLS, 
00592                                             sizeof (unsigned short));
00593 
00594     if (d->img.data == NULL) {
00595         fprintf (stderr, "Could not allocate memory for sample image!\n");
00596         exit (EXIT_FAILURE);
00597     }
00598 
00599     /* fill image with random data (assuming 8 bit image depth -> max
00600        value = 254; 255 is missing value) */
00601 
00602 #ifdef VERBOSE
00603     fprintf (stderr, "RAND_MAX = %d\n", RAND_MAX);
00604 #endif
00605 
00606     for (i = 0; i < NROWS * NCOLS; i++) {
00607         d->img.data[i] = (unsigned short) ((float) rand() / RAND_MAX * 254);
00608 #ifdef VERBOSE
00609         fprintf (stderr, "Value: %d\n", d->img.data[i]);
00610 #endif
00611     }
00612     
00613     /* create our source data */
00614 
00615     d->wmoblock = 11;
00616     d->wmostat  = 164;
00617 
00618     d->meta.year = 2007;
00619     d->meta.month = 12;
00620     d->meta.day = 5;
00621     d->meta.hour = 12;
00622     d->meta.min = 5;
00623     d->meta.radar.lat = 47.06022;
00624     d->meta.radar.lon = 15.45772;
00625     d->meta.radar_height = 355;
00626 
00627     d->img.nw.lat = 50.4371;
00628     d->img.nw.lon = 8.1938;
00629     d->img.ne.lat = 50.3750;
00630     d->img.ne.lon = 19.7773;
00631     d->img.se.lat = 44.5910;
00632     d->img.se.lon = 19.1030;
00633     d->img.sw.lat = 44.6466;
00634     d->img.sw.lon = 8.7324;
00635     d->img.psizex = 1000;
00636     d->img.psizey = 1000;
00637     d->img.nrows = NROWS;
00638     d->img.ncols = NCOLS;
00639     d->img.type = 2;
00640     d->img.grid = 0;
00641     d->img.qual = MISSVAL;
00642 
00643     /* create level slicing table */
00644 
00645     d->img.scale.nvals = 255;
00646 
00647     for (i = 0; i < 255; i++) {
00648         d->img.scale.vals[i] = i * 0.5 - 31.0;
00649     }
00650     d->img.scale.offset = -31;
00651     d->img.scale.increment = 0.5;
00652 
00653     d->proj.type = 2;
00654     d->proj.majax = 6378137;
00655     d->proj.minax = 6356752;
00656     d->proj.orig.lon = 13.333333;
00657     d->proj.orig.lat = 47.0;
00658     d->proj.xoff = 458745;
00659     d->proj.yoff = 364548;
00660     d->proj.stdpar1 = 46.0;
00661     d->proj.stdpar2 = 49.0;
00662 }
00663 
00669 /* end of file */

Generated on Tue Dec 18 16:52:44 2007 for OPERA BUFR software by  doxygen 1.5.4