diff --git a/examples/python/gts_get_keys.py b/examples/python/gts_get_keys.py new file mode 100644 index 000000000..62433cba7 --- /dev/null +++ b/examples/python/gts_get_keys.py @@ -0,0 +1,70 @@ +# Copyright 2005-2015 ECMWF. +# +# This software is licensed under the terms of the Apache Licence Version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +# +# In applying this licence, ECMWF does not waive the privileges and immunities granted to it by +# virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + +# +# Python implementation: bufr_get_keys +# +# Description: how to read values of different type of keys from BUFR messages. +# +# + +import traceback +import sys + +from eccodes import * + +INPUT='../../data/gts/EGRR20150317121020_00493212.DAT' +VERBOSE=1 # verbose error reporting + +def example(): + + # open bufr file + f = open(INPUT) + + cnt=0 + + # loop for the messages in the file + while 1: + # get handle for message + gid = codes_gts_new_from_file(f) + if gid is None: break + + print "message: %s" % cnt + + #---------------------------------------------- + # get values for keys holding a single value + #---------------------------------------------- + keys=[ 'TT', 'AA', 'II', 'CCCC', 'YY', 'GG', 'gg', 'BBB' ] + + for key in keys: + try: + print ' %s: %s' % (key,codes_get(gid,key)) + except CodesInternalError,err: + print 'Error with key="%s" : %s' % (key,err.msg) + + cnt+=1 + + # delete handle + codes_release(gid) + + # close the file + f.close() + +def main(): + try: + example() + except CodesInternalError,err: + if VERBOSE: + traceback.print_exc(file=sys.stderr) + else: + print >>sys.stderr,err.msg + + return 1 + +if __name__ == "__main__": + sys.exit(main()) diff --git a/python/eccode_swig.i b/python/eccode_swig.i index a39f71bb5..526104252 100644 --- a/python/eccode_swig.i +++ b/python/eccode_swig.i @@ -43,6 +43,7 @@ int grib_c_new_from_file(FILE* f, int* INOUT, int headers_only); int grib_c_new_any_from_file(FILE* f, int headers_only, int* INOUT); int grib_c_new_bufr_from_file(FILE* f, int headers_only, int* INOUT); int grib_c_new_gts_from_file(FILE* f, int headers_only, int* INOUT); +int grib_c_new_metar_from_file(FILE* f, int headers_only, int* INOUT); int grib_c_iterator_new(int* INPUT, int* OUTPUT, int* INPUT); int grib_c_keys_iterator_new(int* INPUT, int* OUTPUT, char* name_space); int grib_c_new_from_samples(int* INOUT, char* name); diff --git a/python/eccodes.py b/python/eccodes.py index c32568f1b..291bdf7e6 100644 --- a/python/eccodes.py +++ b/python/eccodes.py @@ -5,6 +5,8 @@ from gribapi import CODES_PRODUCT_ANY from gribapi import grib_new_from_file as codes_grib_new_from_file from gribapi import bufr_new_from_file as codes_bufr_new_from_file +from gribapi import metar_new_from_file as codes_metar_new_from_file +from gribapi import gts_new_from_file as codes_gts_new_from_file from gribapi import any_new_from_file as codes_any_new_from_file from gribapi import codes_new_from_file diff --git a/python/grib_interface.c b/python/grib_interface.c index 85f53eb0b..253af8d0d 100644 --- a/python/grib_interface.c +++ b/python/grib_interface.c @@ -984,7 +984,6 @@ int grib_c_new_gts_from_file(FILE* f,int headers_only, int* gid){ int err = 0; if(f){ - /* h = gts_new_from_file(0,f,headers_only,&err); */ h = gts_new_from_file(0,f,&err); if(h){ @@ -1000,6 +999,26 @@ int grib_c_new_gts_from_file(FILE* f,int headers_only, int* gid){ return GRIB_INVALID_FILE; } +int grib_c_new_metar_from_file(FILE* f,int headers_only, int* gid){ + grib_handle *h = NULL; + int err = 0; + + if(f){ + h = metar_new_from_file(0,f,&err); + + if(h){ + push_handle(h,gid); + return GRIB_SUCCESS; + } else { + *gid=-1; + return GRIB_END_OF_FILE; + } + } + + *gid=-1; + return GRIB_INVALID_FILE; +} + int grib_c_new_any_from_file(FILE* f,int headers_only,int* gid){ grib_handle *h = NULL; int err = 0; diff --git a/python/gribapi.py b/python/gribapi.py index b002ffabd..8d785d069 100644 --- a/python/gribapi.py +++ b/python/gribapi.py @@ -48,6 +48,10 @@ CODES_PRODUCT_GRIB=1 """ GRIB product kind """ CODES_PRODUCT_BUFR=2 """ BUFR product kind """ +CODES_PRODUCT_METAR=3 +""" METAR product kind """ +CODES_PRODUCT_GTS=4 +""" GTS product kind """ # GRIB-51 Skip function arguments type checking if the # environment variable is defined @@ -180,12 +184,47 @@ def gts_new_from_file(fileobj, headers_only = False): else: return gribid +@require(fileobj=file) +def metar_new_from_file(fileobj, headers_only = False): + """ + @brief Load in memory a METAR message from a file. + + The message can be accessed through its id and it will be available\n + until @ref grib_release is called.\n + + The message can be loaded headers only by using the headers_only argument. + Default is to have the headers only option grib_set to off (False). If set to on (True), + data values will be skipped. This will result in a significant performance gain + if one is only interested in browsing through messages to retrieve metadata. + Any attempt to retrieve data values keys when in the headers only mode will + result in a key not found error. + + \b Examples: \ref grib_get_keys.py "grib_get_keys.py" + + @param fileobj python file object + @param headers_only whether or not to load the message with the headers only + @return id of the METAR loaded in memory + @exception GribInternalError + """ + err, gribid = _internal.grib_c_new_metar_from_file(fileobj, headers_only, 0) + if err: + if err == _internal.GRIB_END_OF_FILE: + return None + else: + GRIB_CHECK(err) + else: + return gribid + @require(fileobj=file,product_kind=int) def codes_new_from_file(fileobj, product_kind, headers_only = False): if product_kind == CODES_PRODUCT_GRIB: return grib_new_from_file(fileobj, headers_only) if product_kind == CODES_PRODUCT_BUFR: return bufr_new_from_file(fileobj, headers_only) + if product_kind == CODES_PRODUCT_METAR: + return metar_new_from_file(fileobj, headers_only) + if product_kind == CODES_PRODUCT_GTS: + return gts_new_from_file(fileobj, headers_only) if product_kind == CODES_PRODUCT_ANY: return any_new_from_file(fileobj, headers_only) raise Exception("Invalid product kind: " + product_kind) diff --git a/src/grib_api.h b/src/grib_api.h index 819327605..59ff4b8c1 100644 --- a/src/grib_api.h +++ b/src/grib_api.h @@ -39,7 +39,7 @@ extern "C" { #define DEPRECATED #endif -typedef enum ProductKind {PRODUCT_ANY, PRODUCT_GRIB, PRODUCT_BUFR} ProductKind; +typedef enum ProductKind {PRODUCT_ANY, PRODUCT_GRIB, PRODUCT_BUFR, PRODUCT_METAR, PRODUCT_GTS} ProductKind; #include "eccodes_version.h" diff --git a/src/grib_api_internal.h b/src/grib_api_internal.h index 1491079d1..7091d21ab 100644 --- a/src/grib_api_internal.h +++ b/src/grib_api_internal.h @@ -193,6 +193,8 @@ extern "C" { #define CODES_GRIB 1 #define CODES_BUFR 2 +#define CODES_METAR 3 +#define CODES_GTS 4 #define CODES_BUFR_UNPACK_STRUCTURE 0 #define CODES_BUFR_UNPACK_FLAT 1 diff --git a/src/grib_handle.c b/src/grib_handle.c index 4d4eb7a89..2f52fe6d4 100644 --- a/src/grib_handle.c +++ b/src/grib_handle.c @@ -314,6 +314,10 @@ grib_handle* codes_handle_new_from_file(grib_context* c, FILE* f, ProductKind pr return grib_handle_new_from_file(c, f, error); if (product == PRODUCT_BUFR) return bufr_new_from_file(c, f, error); + if (product == PRODUCT_METAR) + return metar_new_from_file(c, f, error); + if (product == PRODUCT_GTS) + return gts_new_from_file(c, f, error); if (product == PRODUCT_ANY) return any_new_from_file(c, f, error); @@ -329,6 +333,14 @@ grib_handle* codes_bufr_handle_new_from_file(grib_context* c, FILE* f, int* erro { return bufr_new_from_file(c, f, error); } +grib_handle* codes_metar_handle_new_from_file(grib_context* c, FILE* f, int* error) +{ + return metar_new_from_file(c, f, error); +} +grib_handle* codes_gts_handle_new_from_file(grib_context* c, FILE* f, int* error) +{ + return gts_new_from_file(c, f, error); +} grib_handle* grib_handle_new_from_message_copy ( grib_context* c, const void* data, size_t size ) {