mirror of https://github.com/ecmwf/eccodes.git
added grib_merge.c tool
This commit is contained in:
parent
70f24489a4
commit
7400f09067
|
@ -1,40 +1,365 @@
|
|||
Installation Instructions
|
||||
*************************
|
||||
|
||||
The grib_api installation is based on the standard configure utility.
|
||||
It is tested on several platforms and with several compilers. However for some platforms
|
||||
modifications to the installation engine may be required. If you encounter any problem
|
||||
during the installation procedure please send an e-mail with your problem to
|
||||
Software.Support@ecmwf.int.
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
|
||||
2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
|
||||
The only required package for a standard installation is jasper which enables the jpeg2000
|
||||
packing/unpacking algorithm.
|
||||
It is possible to build grib_api without jasper, by using the --disable-jpeg configure option,
|
||||
but to install a fully functional library, its download is recommended.
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. This file is offered as-is,
|
||||
without warranty of any kind.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
Standard Installation
|
||||
Briefly, the shell commands `./configure; make; make install' should
|
||||
configure, build, and install this package. The following
|
||||
more-detailed instructions are generic; see the `README' file for
|
||||
instructions specific to this package. Some packages provide this
|
||||
`INSTALL' file but do not implement all of the features documented
|
||||
below. The lack of an optional feature in a given package is not
|
||||
necessarily a bug. More recommendations for GNU packages can be found
|
||||
in *note Makefile Conventions: (standards)Makefile Conventions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You need `configure.ac' if
|
||||
you want to change it or regenerate `configure' using a newer version
|
||||
of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system.
|
||||
|
||||
Running `configure' might take a while. While running, it prints
|
||||
some messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package, generally using the just-built uninstalled binaries.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation. When installing into a prefix owned by root, it is
|
||||
recommended that the package be configured and built as a regular
|
||||
user, and only the `make install' phase executed with root
|
||||
privileges.
|
||||
|
||||
5. Optionally, type `make installcheck' to repeat any self-tests, but
|
||||
this time using the binaries in their final installed location.
|
||||
This target does not install anything. Running this target as a
|
||||
regular user, particularly if the prior `make install' required
|
||||
root privileges, verifies that the installation completed
|
||||
correctly.
|
||||
|
||||
6. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
7. Often, you can also type `make uninstall' to remove the installed
|
||||
files again. In practice, not all packages have tested that
|
||||
uninstallation works correctly, even though it is required by the
|
||||
GNU Coding Standards.
|
||||
|
||||
8. Some packages, particularly those that use Automake, provide `make
|
||||
distcheck', which can by used by developers to test that all other
|
||||
targets like `make install' and `make uninstall' work correctly.
|
||||
This target is generally not run by end users.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
1. Download grib_api from https://software.ecmwf.int/wiki/display/GRIB/Releases.
|
||||
2. Unpack distribution:
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
> gunzip grib_api-X.tar.gz
|
||||
> tar xf grib_api-X.tar
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
3. Create the directory where to install grib_api say grib_api_dir
|
||||
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||
|
||||
> mkdir grib_api_dir
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
4. Run the configure in the grib_api-X
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
> cd grib_api-X
|
||||
> ./configure --prefix=grib_api_dir
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'. This
|
||||
is known as a "VPATH" build.
|
||||
|
||||
5. make, check and install
|
||||
With a non-GNU `make', it is safer to compile the package for one
|
||||
architecture at a time in the source code directory. After you have
|
||||
installed the package for one architecture, use `make distclean' before
|
||||
reconfiguring for another architecture.
|
||||
|
||||
> make
|
||||
...
|
||||
> make check
|
||||
...
|
||||
> make install
|
||||
...
|
||||
On MacOS X 10.5 and later systems, you can create libraries and
|
||||
executables that work on multiple system types--known as "fat" or
|
||||
"universal" binaries--by specifying multiple `-arch' options to the
|
||||
compiler but only a single `-arch' option to the preprocessor. Like
|
||||
this:
|
||||
|
||||
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CPP="gcc -E" CXXCPP="g++ -E"
|
||||
|
||||
This is not guaranteed to produce working output in all cases, you
|
||||
may have to build one architecture at a time and combine the results
|
||||
using the `lipo' tool if you have problems.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX', where PREFIX must be an
|
||||
absolute file name.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||
PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them. In general, the
|
||||
default for these options is expressed in terms of `${prefix}', so that
|
||||
specifying just `--prefix' will affect all of the other directory
|
||||
specifications that were not explicitly provided.
|
||||
|
||||
The most portable way to affect installation locations is to pass the
|
||||
correct locations to `configure'; however, many packages provide one or
|
||||
both of the following shortcuts of passing variable assignments to the
|
||||
`make install' command line to change installation locations without
|
||||
having to reconfigure or recompile.
|
||||
|
||||
The first method involves providing an override variable for each
|
||||
affected directory. For example, `make install
|
||||
prefix=/alternate/directory' will choose an alternate location for all
|
||||
directory configuration variables that were expressed in terms of
|
||||
`${prefix}'. Any directories that were specified during `configure',
|
||||
but not in terms of `${prefix}', must each be overridden at install
|
||||
time for the entire installation to be relocated. The approach of
|
||||
makefile variable overrides for each directory variable is required by
|
||||
the GNU Coding Standards, and ideally causes no recompilation.
|
||||
However, some platforms have known limitations with the semantics of
|
||||
shared libraries that end up requiring recompilation when using this
|
||||
method, particularly noticeable in packages that use GNU Libtool.
|
||||
|
||||
The second method involves providing the `DESTDIR' variable. For
|
||||
example, `make install DESTDIR=/alternate/directory' will prepend
|
||||
`/alternate/directory' before all installation names. The approach of
|
||||
`DESTDIR' overrides is not required by the GNU Coding Standards, and
|
||||
does not work on platforms that have drive letters. On the other hand,
|
||||
it does better at avoiding recompilation issues, and works well even
|
||||
when some directory options were not specified in terms of `${prefix}'
|
||||
at `configure' time.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Some packages offer the ability to configure how verbose the
|
||||
execution of `make' will be. For these packages, running `./configure
|
||||
--enable-silent-rules' sets the default to minimal output, which can be
|
||||
overridden with `make V=1'; while running `./configure
|
||||
--disable-silent-rules' sets the default to verbose, which can be
|
||||
overridden with `make V=0'.
|
||||
|
||||
Particular systems
|
||||
==================
|
||||
|
||||
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
|
||||
CC is not installed, it is recommended to use the following options in
|
||||
order to use an ANSI C compiler:
|
||||
|
||||
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
|
||||
|
||||
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
|
||||
|
||||
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
|
||||
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
|
||||
a workaround. If GNU CC is not installed, it is therefore recommended
|
||||
to try
|
||||
|
||||
./configure CC="cc"
|
||||
|
||||
and if that doesn't work, try
|
||||
|
||||
./configure CC="cc -nodtk"
|
||||
|
||||
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
|
||||
directory contains several dysfunctional programs; working variants of
|
||||
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
|
||||
in your `PATH', put it _after_ `/usr/bin'.
|
||||
|
||||
On Haiku, software installed for all users goes in `/boot/common',
|
||||
not `/usr/local'. It is recommended to use the following options:
|
||||
|
||||
./configure --prefix=/boot/common
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS
|
||||
KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the option `--target=TYPE' to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
|
||||
an Autoconf bug. Until the bug is fixed you can use this workaround:
|
||||
|
||||
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of all of the options to `configure', and exit.
|
||||
|
||||
`--help=short'
|
||||
`--help=recursive'
|
||||
Print a summary of the options unique to this package's
|
||||
`configure', and exit. The `short' variant lists options used
|
||||
only in the top level, while the `recursive' variant lists options
|
||||
also present in any nested packages.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--prefix=DIR'
|
||||
Use DIR as the installation prefix. *note Installation Names::
|
||||
for more details, including other options available for fine-tuning
|
||||
the installation locations.
|
||||
|
||||
`--no-create'
|
||||
`-n'
|
||||
Run the configure checks, but stop before creating any output
|
||||
files.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ hash_array sequences (defaultSequence,"sequence.def",tablesMasterDir,tablesLocal
|
|||
position offsetSection3;
|
||||
section_length[3] section3Length ;
|
||||
unsigned[1] reserved = 0;
|
||||
unsigned[2] numberOfDataSubsets : dump;
|
||||
unsigned[2] numberOfSubsets : dump;
|
||||
|
||||
if (section2Present && centre==98 && section2Length==52) {
|
||||
|
||||
|
@ -32,7 +32,7 @@ if (section2Present && centre==98 && section2Length==52) {
|
|||
1 = {rdbType = 8; }
|
||||
1 = {rdbType = 12; }
|
||||
}
|
||||
if (isSatelliteType || numberOfDataSubsets>1) {
|
||||
if (isSatelliteType || numberOfSubsets>1) {
|
||||
constant isSatellite=1;
|
||||
} else {
|
||||
constant isSatellite=0;
|
||||
|
@ -44,7 +44,7 @@ if (section2Present && centre==98 && section2Length==52) {
|
|||
meta localLongitude2 bits(keyMore,0,26,-18000000,100000) : dump;
|
||||
meta localLatitude2 bits(keyMore,32,25,-9000000,100000) : dump;
|
||||
|
||||
if (numberOfDataSubsets>255 ||
|
||||
if (numberOfSubsets>255 ||
|
||||
( rdbSubtype>=121 && rdbSubtype <=130 ) ||
|
||||
rdbSubtype==31) {
|
||||
meta ls.umberOfObservations bits(keySat,0,16) : dump,long_type;
|
||||
|
|
|
@ -18,15 +18,15 @@ meta selectGroupNumber bufr_group_number();
|
|||
transient subsetNumber=0;
|
||||
if (compressedData) {
|
||||
meta numericValues bufr_data_array(offsetSection4,offsetBeforeData,offsetEndSection4,section4Length,
|
||||
numberOfDataSubsets,subsetNumber,expandedCodes,expandedFlags,
|
||||
stringValues,elementsDescriptorsIndex,compressedData) ;
|
||||
numberOfSubsets,subsetNumber,expandedCodes,expandedFlags,
|
||||
stringValues,elementsDescriptorsIndex,compressedData) : dump;
|
||||
} else {
|
||||
meta numericValues bufr_data_array(offsetSection4,offsetBeforeData,offsetEndSection4,section4Length,
|
||||
numberOfDataSubsets,subsetNumber,expandedCodes,expandedFlags,
|
||||
stringValues,elementsDescriptorsIndex,compressedData) ;
|
||||
numberOfSubsets,subsetNumber,expandedCodes,expandedFlags,
|
||||
stringValues,elementsDescriptorsIndex,compressedData) : dump;
|
||||
}
|
||||
|
||||
meta unpack unpack_bufr_values(numericValues);
|
||||
meta unpack unpack_bufr_values(numericValues) ;
|
||||
|
||||
section_padding section4Padding;
|
||||
position offsetEndSection4;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
MEMBERS = const char* offsetBeforeDataName
|
||||
MEMBERS = const char* offsetEndSection4Name
|
||||
MEMBERS = const char* section4LengthName
|
||||
MEMBERS = const char* numberOfDataSubsetsName
|
||||
MEMBERS = const char* numberOfSubsetsName
|
||||
MEMBERS = const char* subsetNumberName
|
||||
MEMBERS = const char* expandedDescriptorsName
|
||||
MEMBERS = const char* flagsName
|
||||
|
@ -41,7 +41,7 @@
|
|||
MEMBERS = grib_accessor* expandedAccessor
|
||||
MEMBERS = int* canBeMissing
|
||||
MEMBERS = long subsetNumber
|
||||
MEMBERS = long numberOfDataSubsets
|
||||
MEMBERS = long numberOfSubsets
|
||||
MEMBERS = long compressedData
|
||||
MEMBERS = grib_vdarray* numericValues
|
||||
MEMBERS = grib_vsarray* stringValues
|
||||
|
@ -90,7 +90,7 @@ typedef struct grib_accessor_bufr_data_array {
|
|||
const char* offsetBeforeDataName;
|
||||
const char* offsetEndSection4Name;
|
||||
const char* section4LengthName;
|
||||
const char* numberOfDataSubsetsName;
|
||||
const char* numberOfSubsetsName;
|
||||
const char* subsetNumberName;
|
||||
const char* expandedDescriptorsName;
|
||||
const char* flagsName;
|
||||
|
@ -102,7 +102,7 @@ typedef struct grib_accessor_bufr_data_array {
|
|||
grib_accessor* expandedAccessor;
|
||||
int* canBeMissing;
|
||||
long subsetNumber;
|
||||
long numberOfDataSubsets;
|
||||
long numberOfSubsets;
|
||||
long compressedData;
|
||||
grib_vdarray* numericValues;
|
||||
grib_vsarray* stringValues;
|
||||
|
@ -227,7 +227,7 @@ static void init(grib_accessor* a,const long v, grib_arguments* params)
|
|||
self->offsetBeforeDataName = grib_arguments_get_name(a->parent->h,params,n++);
|
||||
self->offsetEndSection4Name = grib_arguments_get_name(a->parent->h,params,n++);
|
||||
self->section4LengthName = grib_arguments_get_name(a->parent->h,params,n++);
|
||||
self->numberOfDataSubsetsName = grib_arguments_get_name(a->parent->h,params,n++);
|
||||
self->numberOfSubsetsName = grib_arguments_get_name(a->parent->h,params,n++);
|
||||
self->subsetNumberName = grib_arguments_get_name(a->parent->h,params,n++);
|
||||
self->expandedDescriptorsName = grib_arguments_get_name(a->parent->h,params,n++);
|
||||
self->flagsName = grib_arguments_get_name(a->parent->h,params,n++);
|
||||
|
@ -315,7 +315,7 @@ static int get_descriptors(grib_accessor* a) {
|
|||
for (i=0;i<numberOfDescriptors;i++)
|
||||
self->canBeMissing[i]=can_be_missing(self->expanded->v[i]->code);
|
||||
|
||||
ret=grib_get_long(h,self->numberOfDataSubsetsName,&(self->numberOfDataSubsets));
|
||||
ret=grib_get_long(h,self->numberOfSubsetsName,&(self->numberOfSubsets));
|
||||
ret=grib_get_long(h,self->compressedDataName,&(self->compressedData));
|
||||
ret=grib_get_long(h,self->subsetNumberName,&(self->subsetNumber));
|
||||
|
||||
|
@ -339,7 +339,7 @@ static grib_sarray* decode_string_array(grib_context* c,unsigned char* data,long
|
|||
ret=grib_sarray_new(c,10,10);
|
||||
if (width) {
|
||||
grib_context_free(c,sval);
|
||||
for (j=0;j<self->numberOfDataSubsets;j++) {
|
||||
for (j=0;j<self->numberOfSubsets;j++) {
|
||||
sval=(char*)grib_context_malloc_clear(c,width+1);
|
||||
grib_decode_string(data,pos,width,sval);
|
||||
grib_sarray_push(c,ret,sval);
|
||||
|
@ -368,7 +368,7 @@ static grib_darray* decode_double_array(grib_context* c,unsigned char* data,long
|
|||
localWidth=grib_decode_unsigned_long(data,pos,6);
|
||||
ret=grib_darray_new(c,100,100);
|
||||
if (localWidth) {
|
||||
for (j=0;j<self->numberOfDataSubsets;j++) {
|
||||
for (j=0;j<self->numberOfSubsets;j++) {
|
||||
lval=grib_decode_unsigned_long(data,pos,localWidth);
|
||||
if (grib_is_all_bits_one(lval,localWidth) && self->canBeMissing[i]) {
|
||||
dval=GRIB_MISSING_DOUBLE;
|
||||
|
@ -436,12 +436,11 @@ static void decode_element(grib_context* c,grib_accessor_bufr_data_array* self,
|
|||
sar=decode_string_array(c,data,pos,i,self);
|
||||
grib_vsarray_push(c,self->stringValues,sar);
|
||||
index=grib_vsarray_used_size(self->stringValues);
|
||||
dar=grib_darray_new(c,self->numberOfDataSubsets,10);
|
||||
dar=grib_darray_new(c,self->numberOfSubsets,10);
|
||||
sar_size=grib_sarray_used_size(sar);
|
||||
index=self->numberOfDataSubsets*(index-1);
|
||||
for (ii=1;ii<=self->numberOfDataSubsets;ii++) {
|
||||
index=self->numberOfSubsets*(index-1);
|
||||
for (ii=1;ii<=self->numberOfSubsets;ii++) {
|
||||
x=(index+ii)*1000+self->expanded->v[i]->width/8;
|
||||
/* x=index*1000+strlen(sar->v[idx]); */
|
||||
grib_darray_push(c,dar,x);
|
||||
}
|
||||
grib_vdarray_push(c,self->numericValues,dar);
|
||||
|
@ -568,9 +567,10 @@ static void push_zero_element(grib_accessor_bufr_data_array* self,grib_darray* d
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
static grib_accessor* create_accessor_from_descriptor(grib_accessor* a,long ide,long subset) {
|
||||
grib_accessor_bufr_data_array *self =(grib_accessor_bufr_data_array*)a;
|
||||
int idx=0;
|
||||
grib_section* section=0;
|
||||
grib_accessor* elementAccessor=NULL;
|
||||
grib_action creator = {0, };
|
||||
creator.op = "bufr_data_element";
|
||||
|
@ -578,13 +578,22 @@ static grib_accessor* create_accessor_from_descriptor(grib_accessor* a,long ide,
|
|||
creator.flags = GRIB_ACCESSOR_FLAG_DUMP;
|
||||
creator.set = 0;
|
||||
|
||||
creator.name=self->expanded->v[self->elementsDescriptorsIndex->v[ide]]->name;
|
||||
elementAccessor = grib_accessor_factory(section, &creator, 0, NULL);
|
||||
accessor_bufr_data_element_set_index(elementAccessor,ide);
|
||||
accessor_bufr_data_element_set_descriptors(elementAccessor,self->expanded);
|
||||
accessor_bufr_data_element_set_numericValues(elementAccessor,self->numericValues);
|
||||
accessor_bufr_data_element_set_stringValue(elementAccessor,self->stringValue);
|
||||
accessor_bufr_data_element_set_compressedData(elementAccessor,self->compressedData);
|
||||
idx = self->compressedData ? self->elementsDescriptorsIndex->v[0]->v[ide] :
|
||||
self->elementsDescriptorsIndex->v[ide]->v[subset];
|
||||
|
||||
creator.name=self->expanded->v[idx]->shortName;
|
||||
if (creator.name) {
|
||||
section=a->sub_section;
|
||||
elementAccessor = grib_accessor_factory(section, &creator, 0, NULL);
|
||||
accessor_bufr_data_element_set_index(elementAccessor,ide);
|
||||
accessor_bufr_data_element_set_descriptors(elementAccessor,self->expanded);
|
||||
accessor_bufr_data_element_set_numericValues(elementAccessor,self->numericValues);
|
||||
accessor_bufr_data_element_set_stringValues(elementAccessor,self->stringValues);
|
||||
accessor_bufr_data_element_set_compressedData(elementAccessor,self->compressedData);
|
||||
accessor_bufr_data_element_set_type(elementAccessor,self->expanded->v[idx]->type);
|
||||
accessor_bufr_data_element_set_numberOfSubsets(elementAccessor,self->numberOfSubsets);
|
||||
accessor_bufr_data_element_set_subsetNumber(elementAccessor,subset);
|
||||
}
|
||||
|
||||
return elementAccessor;
|
||||
}
|
||||
|
@ -592,23 +601,23 @@ static grib_accessor* create_accessor_from_descriptor(grib_accessor* a,long ide,
|
|||
static int create_keys(grib_accessor* a) {
|
||||
grib_accessor_bufr_data_array *self =(grib_accessor_bufr_data_array*)a;
|
||||
int err=0;
|
||||
grib_accessor* elementAccessor=0;
|
||||
long iss,end,elementsInSubset,ide;
|
||||
grib_context* c=a->parent->h->context;
|
||||
grib_section* section=a->sub_section;
|
||||
|
||||
end= self->compressedData ? 1 : self->numberOfDataSubsets;
|
||||
end= self->compressedData ? 1 : self->numberOfSubsets;
|
||||
|
||||
for (iss=0;iss<end;iss++) {
|
||||
elementsInSubset= self->compressedData ? grib_viarray_used_size(self->elementsDescriptorsIndex) :
|
||||
elementsInSubset= self->compressedData ? grib_iarray_used_size(self->elementsDescriptorsIndex->v[0]) :
|
||||
grib_iarray_used_size(self->elementsDescriptorsIndex->v[iss]);
|
||||
for (ide=0;ide<elementsInSubset;ide++) {
|
||||
elementAccessor=create_accessor_from_descriptor(a,ide);
|
||||
grib_push_accessor(elementAccessor,a->subsection->block);
|
||||
elementAccessor=create_accessor_from_descriptor(a,ide,iss);
|
||||
if (elementAccessor) grib_push_accessor(elementAccessor,section->block);
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
*/
|
||||
|
||||
#define MAX_NESTED_REPLICATIONS 8
|
||||
|
||||
|
@ -662,7 +671,7 @@ static int decode_elements(grib_accessor* a) {
|
|||
if (self->elementsDescriptorsIndex) grib_viarray_delete(c,self->elementsDescriptorsIndex);
|
||||
self->elementsDescriptorsIndex=grib_viarray_new(c,100,100);
|
||||
|
||||
end= self->compressedData ? 1 : self->numberOfDataSubsets;
|
||||
end= self->compressedData ? 1 : self->numberOfSubsets;
|
||||
|
||||
numberOfDescriptors=grib_bufr_descriptors_array_used_size(self->expanded);
|
||||
|
||||
|
@ -837,7 +846,7 @@ static int decode_elements(grib_accessor* a) {
|
|||
}
|
||||
}
|
||||
|
||||
/* err=create_keys(a); */
|
||||
err=create_keys(a);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -863,9 +872,9 @@ static int value_count(grib_accessor* a,long* count)
|
|||
|
||||
err=grib_get_long(a->parent->h,self->subsetNumberName,&subsetNumber);
|
||||
if (err) return err;
|
||||
if (subsetNumber>self->numberOfDataSubsets) {
|
||||
if (subsetNumber>self->numberOfSubsets) {
|
||||
err=GRIB_INVALID_KEY_VALUE;
|
||||
grib_context_log(c,GRIB_LOG_ERROR,"%s=%ld is too big, %s=%ld",self->subsetNumberName,self->numberOfDataSubsetsName);
|
||||
grib_context_log(c,GRIB_LOG_ERROR,"%s=%ld is too big, %s=%ld",self->subsetNumberName,self->numberOfSubsetsName);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -874,14 +883,14 @@ static int value_count(grib_accessor* a,long* count)
|
|||
|
||||
*count=l;
|
||||
if (subsetNumber<=0) {
|
||||
*count *= self->numberOfDataSubsets;
|
||||
*count *= self->numberOfSubsets;
|
||||
}
|
||||
} else {
|
||||
if (subsetNumber>0) {
|
||||
*count=grib_iarray_used_size(self->elementsDescriptorsIndex->v[subsetNumber-1]);
|
||||
} else {
|
||||
*count=0;
|
||||
for (i=0;i<self->numberOfDataSubsets;i++)
|
||||
for (i=0;i<self->numberOfSubsets;i++)
|
||||
*count+=grib_iarray_used_size(self->elementsDescriptorsIndex->v[i]);
|
||||
}
|
||||
}
|
||||
|
@ -904,11 +913,11 @@ static int unpack_double(grib_accessor* a, double* val, size_t *len) {
|
|||
l=grib_vdarray_used_size(self->numericValues);
|
||||
err=grib_get_long(a->parent->h,self->subsetNumberName,&n);
|
||||
if (err) return err;
|
||||
err=grib_get_long(a->parent->h,self->numberOfDataSubsetsName,&numberOfSubsets);
|
||||
err=grib_get_long(a->parent->h,self->numberOfSubsetsName,&numberOfSubsets);
|
||||
if (err) return err;
|
||||
if (n>numberOfSubsets) {
|
||||
err=GRIB_INVALID_KEY_VALUE;
|
||||
grib_context_log(c,GRIB_LOG_ERROR,"%s=%ld is too big, %s=%ld",self->subsetNumberName,self->numberOfDataSubsetsName);
|
||||
grib_context_log(c,GRIB_LOG_ERROR,"%s=%ld is too big, %s=%ld",self->subsetNumberName,self->numberOfSubsetsName);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
MEMBERS = long index
|
||||
MEMBERS = int type
|
||||
MEMBERS = long compressedData
|
||||
MEMBERS = long subsetNumber
|
||||
MEMBERS = long numberOfSubsets
|
||||
MEMBERS = bufr_descriptors_array* descriptors
|
||||
MEMBERS = grib_vdarray* numericValues
|
||||
MEMBERS = grib_vsarray* stringValues
|
||||
|
@ -63,6 +65,8 @@ typedef struct grib_accessor_bufr_data_element {
|
|||
long index;
|
||||
int type;
|
||||
long compressedData;
|
||||
long subsetNumber;
|
||||
long numberOfSubsets;
|
||||
bufr_descriptors_array* descriptors;
|
||||
grib_vdarray* numericValues;
|
||||
grib_vsarray* stringValues;
|
||||
|
@ -157,6 +161,16 @@ void accessor_bufr_data_element_set_type(grib_accessor* a,int type) {
|
|||
self->type=type;
|
||||
}
|
||||
|
||||
void accessor_bufr_data_element_set_numberOfSubsets(grib_accessor* a,long numberOfSubsets) {
|
||||
grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a;
|
||||
self->numberOfSubsets=numberOfSubsets;
|
||||
}
|
||||
|
||||
void accessor_bufr_data_element_set_subsetNumber(grib_accessor* a,long subsetNumber) {
|
||||
grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a;
|
||||
self->subsetNumber=subsetNumber;
|
||||
}
|
||||
|
||||
void accessor_bufr_data_element_set_compressedData(grib_accessor* a,int compressedData) {
|
||||
grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a;
|
||||
self->compressedData=compressedData;
|
||||
|
@ -184,9 +198,8 @@ void accessor_bufr_data_element_set_elementsDescriptorsIndex(grib_accessor* a,gr
|
|||
|
||||
static void init(grib_accessor* a, const long len, grib_arguments* params) {
|
||||
|
||||
/* grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; */
|
||||
a->length = 0;
|
||||
/* a->flags |= GRIB_ACCESSOR_FLAG_READ_ONLY; */
|
||||
a->flags |= GRIB_ACCESSOR_FLAG_READ_ONLY;
|
||||
}
|
||||
|
||||
static void dump(grib_accessor* a, grib_dumper* dumper)
|
||||
|
@ -208,29 +221,89 @@ static void dump(grib_accessor* a, grib_dumper* dumper)
|
|||
|
||||
static int unpack_string_array (grib_accessor* a, char** val, size_t *len)
|
||||
{
|
||||
/* grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; */
|
||||
grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a;
|
||||
|
||||
return GRIB_NOT_IMPLEMENTED;
|
||||
int ret=0,i,idx;
|
||||
long count=0;
|
||||
grib_context* c=a->parent->h->context;
|
||||
|
||||
value_count(a,&count);
|
||||
|
||||
if (*len<count) return GRIB_ARRAY_TOO_SMALL;
|
||||
|
||||
if (self->compressedData) {
|
||||
for (i=0;i<count;i++) {
|
||||
idx=(int)self->numericValues->v[self->index]->v[i]/1000;
|
||||
val[i]=grib_context_strdup(c,self->stringValues->v[idx]->v[i]);
|
||||
}
|
||||
} else {
|
||||
idx=(int)self->numericValues->v[self->subsetNumber]->v[self->index]/1000;
|
||||
val[0]=grib_context_strdup(c,self->stringValues->v[self->subsetNumber]->v[idx]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int unpack_string (grib_accessor* a, char* val, size_t *len)
|
||||
{
|
||||
return GRIB_NOT_IMPLEMENTED;
|
||||
sprintf(val,"test");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unpack_long (grib_accessor* a, long* val, size_t *len)
|
||||
{
|
||||
return GRIB_NOT_IMPLEMENTED;
|
||||
grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a;
|
||||
int ret=0,i;
|
||||
long count=0;
|
||||
|
||||
value_count(a,&count);
|
||||
|
||||
if (*len<count) return GRIB_ARRAY_TOO_SMALL;
|
||||
|
||||
if (self->compressedData) {
|
||||
for (i=0;i<count;i++) {
|
||||
val[i]=(long)self->numericValues->v[self->index]->v[i];
|
||||
}
|
||||
} else {
|
||||
val[0]=(long)self->numericValues->v[self->subsetNumber]->v[self->index];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int unpack_double (grib_accessor* a, double* val, size_t *len)
|
||||
{
|
||||
return GRIB_NOT_IMPLEMENTED;
|
||||
grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a;
|
||||
int ret=0,i;
|
||||
long count=0;
|
||||
|
||||
value_count(a,&count);
|
||||
|
||||
if (*len<count) return GRIB_ARRAY_TOO_SMALL;
|
||||
|
||||
if (self->compressedData) {
|
||||
for (i=0;i<count;i++) {
|
||||
val[i]=self->numericValues->v[self->index]->v[i];
|
||||
}
|
||||
} else {
|
||||
val[0]=self->numericValues->v[self->subsetNumber]->v[self->index];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int value_count(grib_accessor* a,long* count)
|
||||
{
|
||||
return 0;
|
||||
int ret,size;
|
||||
grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a;
|
||||
|
||||
if (!self->compressedData) return 1;
|
||||
|
||||
size=grib_darray_used_size(self->numericValues->v[self->index]);
|
||||
|
||||
ret= size == 1 ? 1 : self->numberOfSubsets;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void destroy(grib_context* context,grib_accessor* a)
|
||||
|
@ -239,15 +312,27 @@ static void destroy(grib_context* context,grib_accessor* a)
|
|||
|
||||
static int get_native_type(grib_accessor* a){
|
||||
grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a;
|
||||
int ret=GRIB_TYPE_DOUBLE;
|
||||
|
||||
/*
|
||||
if (self->compressedData) {
|
||||
|
||||
} else {
|
||||
switch (self->type) {
|
||||
case BUFR_DESCRIPTOR_TYPE_STRING:
|
||||
ret=GRIB_TYPE_STRING;
|
||||
break;
|
||||
case BUFR_DESCRIPTOR_TYPE_DOUBLE:
|
||||
ret=GRIB_TYPE_DOUBLE;
|
||||
break;
|
||||
case BUFR_DESCRIPTOR_TYPE_LONG:
|
||||
ret=GRIB_TYPE_LONG;
|
||||
break;
|
||||
case BUFR_DESCRIPTOR_TYPE_TABLE:
|
||||
ret=GRIB_TYPE_LONG;
|
||||
break;
|
||||
case BUFR_DESCRIPTOR_TYPE_FLAG:
|
||||
ret=GRIB_TYPE_LONG;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
return self->type;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ or edit "accessor.class" and rerun ./make_class.pl
|
|||
|
||||
static int pack_double(grib_accessor*, const double* val,size_t *len);
|
||||
static int unpack_double(grib_accessor*, double* val,size_t *len);
|
||||
static int value_count(grib_accessor*, long*);
|
||||
static int value_count(grib_accessor*,long*);
|
||||
static void init(grib_accessor*,const long, grib_arguments* );
|
||||
static void init_class(grib_accessor_class*);
|
||||
|
||||
|
@ -93,7 +93,7 @@ static grib_accessor_class _grib_accessor_class_data_ccsds_packing = {
|
|||
0, /* get native type */
|
||||
0, /* get sub_section */
|
||||
0, /* grib_pack procedures long */
|
||||
0, /* grib_pack procedures long */
|
||||
0, /* grib_pack procedures long */
|
||||
0, /* grib_pack procedures long */
|
||||
0, /* grib_unpack procedures long */
|
||||
&pack_double, /* grib_pack procedures double */
|
||||
|
@ -136,6 +136,8 @@ static void init_class(grib_accessor_class* c)
|
|||
c->unpack_long = (*(c->super))->unpack_long;
|
||||
c->pack_string = (*(c->super))->pack_string;
|
||||
c->unpack_string = (*(c->super))->unpack_string;
|
||||
c->pack_string_array = (*(c->super))->pack_string_array;
|
||||
c->unpack_string_array = (*(c->super))->unpack_string_array;
|
||||
c->pack_bytes = (*(c->super))->pack_bytes;
|
||||
c->unpack_bytes = (*(c->super))->unpack_bytes;
|
||||
c->pack_expression = (*(c->super))->pack_expression;
|
||||
|
|
|
@ -145,7 +145,7 @@ typedef struct grib_accessor_bufr_compressed_data {
|
|||
const char* offsetBeforeDataName;
|
||||
const char* offsetEndSection4Name;
|
||||
const char* section4LengthName;
|
||||
const char* numberOfDataSubsetsName;
|
||||
const char* numberOfSubsetsName;
|
||||
const char* subsetNumberName;
|
||||
const char* expandedDescriptorsName;
|
||||
const char* elementsName;
|
||||
|
@ -169,7 +169,7 @@ typedef struct grib_accessor_bufr_compressed_data {
|
|||
long* scale;
|
||||
long* width;
|
||||
long numberOfElements;
|
||||
long numberOfDataSubsets;
|
||||
long numberOfSubsets;
|
||||
size_t numberOfDescriptors;
|
||||
double* values;
|
||||
int* is_constant;
|
||||
|
|
|
@ -169,7 +169,7 @@ double rint(double x);
|
|||
#define GRIB_HANDLE_BIG_ECMWF_GRIB1 1
|
||||
|
||||
#define MAX_FILE_HANDLES_WITH_MULTI 10
|
||||
#define ACCESSORS_ARRAY_SIZE 2100
|
||||
#define ACCESSORS_ARRAY_SIZE 20000
|
||||
#define MAX_NUM_CONCEPTS 2000
|
||||
#define MAX_NUM_HASH_ARRAY 2000
|
||||
|
||||
|
|
|
@ -253,6 +253,8 @@ size_t grib_viarray_used_size(grib_viarray *v);
|
|||
/* grib_accessor_class_bufr_data_element.c */
|
||||
void accessor_bufr_data_element_set_index(grib_accessor *a, long index);
|
||||
void accessor_bufr_data_element_set_type(grib_accessor *a, int type);
|
||||
void accessor_bufr_data_element_set_numberOfSubsets(grib_accessor *a, long numberOfSubsets);
|
||||
void accessor_bufr_data_element_set_subsetNumber(grib_accessor *a, long subsetNumber);
|
||||
void accessor_bufr_data_element_set_compressedData(grib_accessor *a, int compressedData);
|
||||
void accessor_bufr_data_element_set_descriptors(grib_accessor *a, bufr_descriptors_array *descriptors);
|
||||
void accessor_bufr_data_element_set_numericValues(grib_accessor *a, grib_vdarray *numericValues);
|
||||
|
|
|
@ -61,9 +61,9 @@ typedef struct grib_nearest_lambert_conformal{
|
|||
double* lons;
|
||||
int lons_count;
|
||||
double* distances;
|
||||
int* k; /* index */
|
||||
int* i; /* index into the lons array */
|
||||
int* j; /* index into the lats array */
|
||||
int* k;
|
||||
int* i;
|
||||
int* j;
|
||||
const char* Ni;
|
||||
const char* Nj;
|
||||
} grib_nearest_lambert_conformal;
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#
|
||||
|
||||
|
||||
set -ex
|
||||
|
||||
. ./include.sh
|
||||
|
||||
REDIRECT=/dev/null
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
# virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
|
||||
#
|
||||
|
||||
set -e
|
||||
set -ex
|
||||
|
||||
. ./include.sh
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ ecbuild_add_library( TARGET grib_tools
|
|||
|
||||
list( APPEND grib_tools_bins
|
||||
grib_keys grib_histogram grib_error grib_add big2gribex
|
||||
grib_debug grib_info grib_filter grib_ls grib_dump
|
||||
grib_debug grib_info grib_filter grib_ls grib_dump grib_merge
|
||||
grib2ppm grib_set grib_get grib_get_data grib_copy grib_repair
|
||||
grib_packing grib_cmp grib_convert grib_distance grib_corruption_check
|
||||
grib_compare parser grib_count grib_index_build
|
||||
|
|
|
@ -14,7 +14,7 @@ libgrib_tools_la_SOURCES = grib_tools.c \
|
|||
dist_bin_SCRIPTS = bufr_compare_dir
|
||||
|
||||
bin_PROGRAMS = grib_keys grib_histogram grib_error grib_add big2gribex \
|
||||
grib_debug grib_info grib_filter grib_ls grib_dump \
|
||||
grib_debug grib_info grib_filter grib_ls grib_dump grib_merge \
|
||||
grib2ppm grib_set grib_get grib_get_data grib_copy grib_repair \
|
||||
grib_packing grib_cmp grib_convert grib_distance grib_corruption_check\
|
||||
grib_compare grib_list_keys parser grib_count grib_index_build grib1to2 \
|
||||
|
@ -32,6 +32,7 @@ noinst_PROGRAMS = gaussian grib_diff mars_request xref all_keys #compile #dumpl
|
|||
|
||||
grib_corruption_check_SOURCES = grib_corruption_check.c
|
||||
grib_moments_SOURCES = grib_moments.c
|
||||
grib_merge_SOURCES = grib_merge.c
|
||||
grib_to_netcdf_SOURCES = grib_to_netcdf.c
|
||||
grib_to_json_SOURCES = grib_to_json.c
|
||||
grib_dump_SOURCES = grib_dump.c
|
||||
|
|
|
@ -139,6 +139,7 @@ int grib_tool_new_handle_action(grib_runtime_options* options, grib_handle* h) {
|
|||
grib_set_flag(h,options->print_keys[i].name,GRIB_ACCESSOR_FLAG_DUMP);
|
||||
|
||||
if (json) {
|
||||
grib_set_long(h,"unpack",1);
|
||||
} else {
|
||||
sprintf(tmp,"MESSAGE %d ( length=%ld )",options->handle_count,length);
|
||||
if (!grib_options_on("C"))
|
||||
|
|
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* Copyright 2005-2012 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* C Implementation: grib_copy
|
||||
*
|
||||
* Author: Enrico Fucile <enrico.fucile@ecmwf.int>
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "grib_tools.h"
|
||||
|
||||
#define MAX_KEY_VALUES 100
|
||||
|
||||
grib_handle *hh=0;
|
||||
grib_values key_values[MAX_KEY_VALUES];
|
||||
int key_values_size=MAX_KEY_VALUES;
|
||||
|
||||
char* grib_tool_description="Merge two fields with identical parameters and different geografical area";
|
||||
char* grib_tool_name="grib_merge";
|
||||
char* grib_tool_usage="[options] file file ... output_file";
|
||||
|
||||
grib_option grib_options[]={
|
||||
/* {id, args, help}, on, command_line, value */
|
||||
{"f",0,0,0,1,0},
|
||||
{"c",0,0,1,0,0},
|
||||
{"r",0,0,0,1,0},
|
||||
{"q",0,0,1,0,0},
|
||||
{"p:",0,0,1,1,0},
|
||||
{"P:",0,0,0,1,0},
|
||||
{"B:",0,0,1,1,"md5Product"},
|
||||
{"V",0,0,0,1,0},
|
||||
{"W:",0,0,0,1,0},
|
||||
{"M",0,0,0,1,0},
|
||||
{"U",0,0,1,0,0},
|
||||
{"H",0,0,1,0,0},
|
||||
{"T:",0,0,1,0,"G"},
|
||||
{"S",0,0,1,0,0},
|
||||
{"g",0,0,0,1,0},
|
||||
{"G",0,0,0,1,0},
|
||||
{"7",0,0,0,1,0},
|
||||
{"v",0,0,0,1,0}
|
||||
};
|
||||
|
||||
int grib_options_count=sizeof(grib_options)/sizeof(grib_option);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int ret=grib_tool(argc,argv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int grib_tool_before_getopt(grib_runtime_options* options) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int grib_tool_init(grib_runtime_options* options) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int grib_tool_new_filename_action(grib_runtime_options* options,const char* file) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int grib_tool_new_file_action(grib_runtime_options* options,grib_tools_file* file) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int idx(double lat,double lon,double latFirst,double lonFirst,double latLast,double lonLast,
|
||||
long Ni,double di,double dj) {
|
||||
long ilon,ilat;
|
||||
if ((ilon=(lon-lonFirst)/di) < 0 ) return -1;
|
||||
if ((ilat=(latFirst-lat)/dj) < 0 ) return -1;
|
||||
if (lon>lonLast) {
|
||||
if (lonLast==180) {
|
||||
lon-=360;
|
||||
ilon=(lon-lonFirst)/di;
|
||||
} else
|
||||
return -1;
|
||||
}
|
||||
if (lat<latLast) return -1;
|
||||
if ((ilat=(latFirst-lat)/dj) < 0 ) return -1;
|
||||
return ilon+ilat*Ni;
|
||||
}
|
||||
|
||||
grib_handle* merge(grib_handle* h1,grib_handle* h2) {
|
||||
char s1[100]={0,};
|
||||
size_t len1;
|
||||
char s2[100]={0,};
|
||||
size_t len2;
|
||||
size_t sn;
|
||||
long l1,l2;
|
||||
double di,dj,di1,dj1,di2,dj2;
|
||||
long bitmapPresent;
|
||||
long n=0,n1,n2;
|
||||
double latFirst1,latFirst2,latFirst;
|
||||
double latLast1,latLast2,latLast;
|
||||
double lonFirst1,lonFirst2,lonFirst;
|
||||
double lonLast1,lonLast2,lonLast;
|
||||
double missingValue;
|
||||
double *v=0,*v1=0,*v2=0,*lat1=0,*lat2=0,*lon1=0,*lon2=0,*lat=0,*lon=0;
|
||||
long i,j,iscan,jscan,Ni,Nj,idj,idi;
|
||||
long Ni1,Nj1,Ni2,Nj2;
|
||||
grib_handle* h=NULL;
|
||||
grib_context* c;
|
||||
int err=0;
|
||||
/*
|
||||
int dump_flags= GRIB_DUMP_FLAG_CODED
|
||||
| GRIB_DUMP_FLAG_OCTECT
|
||||
| GRIB_DUMP_FLAG_VALUES
|
||||
| GRIB_DUMP_FLAG_READ_ONLY;
|
||||
|
||||
*/
|
||||
c=grib_context_get_default();
|
||||
/* same products? */
|
||||
if (grib_key_equal(h1,h2,"md5Product",GRIB_TYPE_STRING,&err)==0 && err==0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* can we do it?*/
|
||||
|
||||
len2=sizeof(s2)/sizeof(*s2);
|
||||
err=grib_get_string(h2,"gridType",s2,&len2);
|
||||
if (strcmp(s2,"regular_ll")) {
|
||||
grib_context_log(h1->context,GRIB_LOG_WARNING,"gridType=%s not supported",s2);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len1=sizeof(s1)/sizeof(*s1);
|
||||
err=grib_get_string(h1,"gridType",s1,&len1);
|
||||
if (strcmp(s1,"regular_ll")) {
|
||||
grib_context_log(h1->context,GRIB_LOG_WARNING,"gridType=%s not supported",s1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!grib_key_equal(h1,h2,"iDirectionIncrementInDegrees",GRIB_TYPE_DOUBLE,&err) ) {
|
||||
grib_context_log(h1->context,GRIB_LOG_WARNING,
|
||||
"unable to merge: different iDirectionIncrementInDegrees");
|
||||
return NULL;
|
||||
}
|
||||
if (!grib_key_equal(h1,h2,"jDirectionIncrementInDegrees",GRIB_TYPE_DOUBLE,&err) ) {
|
||||
grib_context_log(h1->context,GRIB_LOG_WARNING,
|
||||
"unable to merge: different jDirectionIncrementInDegrees");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
grib_get_long(h1,"latitudeOfFirstGridPoint",&l1);
|
||||
grib_get_long(h2,"latitudeOfFirstGridPoint",&l2);
|
||||
grib_get_long(h2,"jDirectionIncrement",&idj);
|
||||
if ( (l1-l2) % idj ) {
|
||||
grib_context_log(h1->context,GRIB_LOG_WARNING, "unable to merge: incompatible grid");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
grib_get_long(h1,"longitudeOfFirstGridPoint",&l1);
|
||||
grib_get_long(h2,"longitudeOfFirstGridPoint",&l2);
|
||||
grib_get_long(h2,"iDirectionIncrement",&idi);
|
||||
if ( (l1-l2) % idi ) {
|
||||
grib_context_log(h1->context,GRIB_LOG_WARNING, "unable to merge: incompatible grid");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* yes we can!*/
|
||||
|
||||
/* do we have something to do?*/
|
||||
|
||||
if ( grib_key_equal(h1,h2,"latitudeOfFirstGridPointInDegrees",GRIB_TYPE_DOUBLE,&err) &&
|
||||
grib_key_equal(h1,h2,"latitudeOfLastGridPointInDegrees",GRIB_TYPE_DOUBLE,&err) &&
|
||||
grib_key_equal(h1,h2,"longitudeOfFirstGridPointInDegrees",GRIB_TYPE_DOUBLE,&err) &&
|
||||
grib_key_equal(h1,h2,"longitudeOfLastGridPointInDegrees",GRIB_TYPE_DOUBLE,&err)
|
||||
) {
|
||||
/* no we don't */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* yes we do! */
|
||||
|
||||
/* check scanning mode */
|
||||
grib_get_long(h1,"iScansNegatively",&iscan);
|
||||
if (iscan) grib_set_long(h1,"swapScanningLon",1);
|
||||
grib_get_long(h2,"iScansNegatively",&iscan);
|
||||
if (iscan) grib_set_long(h2,"swapScanningLon",1);
|
||||
|
||||
grib_get_long(h1,"jScansPositively",&jscan);
|
||||
if (jscan) grib_set_long(h1,"swapScanningLat",1);
|
||||
grib_get_long(h2,"jScansPositively",&jscan);
|
||||
if (jscan) grib_set_long(h2,"swapScanningLat",1);
|
||||
|
||||
grib_get_double(h1,"latitudeOfFirstGridPointInDegrees",&latFirst1);
|
||||
grib_get_double(h2,"latitudeOfFirstGridPointInDegrees",&latFirst2);
|
||||
grib_get_double(h1,"longitudeOfFirstGridPointInDegrees",&lonFirst1);
|
||||
grib_get_double(h2,"longitudeOfFirstGridPointInDegrees",&lonFirst2);
|
||||
|
||||
latFirst = latFirst1>latFirst2 ? latFirst1 : latFirst2;
|
||||
lonFirst = lonFirst1<lonFirst2 ? lonFirst1 : lonFirst2;
|
||||
|
||||
grib_get_double(h1,"latitudeOfLastGridPointInDegrees",&latLast1);
|
||||
grib_get_double(h2,"latitudeOfLastGridPointInDegrees",&latLast2);
|
||||
grib_get_double(h1,"longitudeOfLastGridPointInDegrees",&lonLast1);
|
||||
grib_get_double(h2,"longitudeOfLastGridPointInDegrees",&lonLast2);
|
||||
|
||||
latLast = latLast1<latLast2 ? latLast1 : latLast2;
|
||||
lonLast = lonLast1>lonLast2 ? lonLast1 : lonLast2;
|
||||
|
||||
grib_get_double(h1,"iDirectionIncrementInDegrees",&di1);
|
||||
grib_get_double(h1,"jDirectionIncrementInDegrees",&dj1);
|
||||
grib_get_double(h2,"iDirectionIncrementInDegrees",&di2);
|
||||
grib_get_double(h2,"jDirectionIncrementInDegrees",&dj2);
|
||||
grib_get_double(h1,"iDirectionIncrementInDegrees",&di);
|
||||
grib_get_double(h1,"jDirectionIncrementInDegrees",&dj);
|
||||
grib_get_long(h1,"Ni",&Ni1);
|
||||
grib_get_long(h1,"Nj",&Nj1);
|
||||
grib_get_long(h2,"Ni",&Ni2);
|
||||
grib_get_long(h2,"Nj",&Nj2);
|
||||
|
||||
if (lonFirst==0 && lonLast==360) lonLast-=di;
|
||||
if (lonFirst==-180 && lonLast==180) {
|
||||
lonFirst=0;
|
||||
lonLast=360-di;
|
||||
}
|
||||
|
||||
/* create new grib for bigger area*/
|
||||
h=grib_handle_clone(h1);
|
||||
grib_set_double(h,"latitudeOfFirstGridPointInDegrees",latFirst);
|
||||
grib_set_double(h,"longitudeOfFirstGridPointInDegrees",lonFirst);
|
||||
grib_set_double(h,"latitudeOfLastGridPointInDegrees",latLast);
|
||||
grib_set_double(h,"longitudeOfLastGridPointInDegrees",lonLast);
|
||||
Ni=fabs(lonLast-lonFirst)/di+1;
|
||||
Nj=fabs(latLast-latFirst)/dj+1;
|
||||
|
||||
grib_set_long(h,"Ni",Ni);
|
||||
grib_set_long(h,"Nj",Nj);
|
||||
|
||||
grib_get_long(h,"bitmapPresent",&bitmapPresent);
|
||||
if (!bitmapPresent) grib_set_long(h,"bitmapPresent",1);
|
||||
|
||||
grib_get_long(h,"numberOfPoints",&n);
|
||||
grib_get_double(h,"missingValue",&missingValue);
|
||||
v=grib_context_malloc_clear(h->context,sizeof(double)*n);
|
||||
for (i=0;i<n;i++) v[i]=1.0;
|
||||
sn=n;
|
||||
grib_set_double_array(h,"values",v,sn);
|
||||
for (i=0;i<n;i++) v[i]=missingValue;
|
||||
lat=grib_context_malloc_clear(h->context,sizeof(double)*n);
|
||||
lon=grib_context_malloc_clear(h->context,sizeof(double)*n);
|
||||
sn=n;
|
||||
grib_get_double_array(h,"latitudes",lat,&sn);
|
||||
grib_get_double_array(h,"longitudes",lon,&sn);
|
||||
|
||||
grib_get_long(h1,"numberOfPoints",&n1);
|
||||
v1=grib_context_malloc_clear(h->context,sizeof(double)*n1);
|
||||
lat1=grib_context_malloc_clear(h->context,sizeof(double)*n1);
|
||||
lon1=grib_context_malloc_clear(h->context,sizeof(double)*n1);
|
||||
sn=n1;
|
||||
grib_get_double_array(h1,"latitudes",lat1,&sn);
|
||||
grib_get_double_array(h1,"longitudes",lon1,&sn);
|
||||
grib_get_double_array(h1,"values",v1,&sn);
|
||||
|
||||
grib_get_long(h2,"numberOfPoints",&n2);
|
||||
v2=grib_context_malloc_clear(h->context,sizeof(double)*n2);
|
||||
lat2=grib_context_malloc_clear(h->context,sizeof(double)*n2);
|
||||
lon2=grib_context_malloc_clear(h->context,sizeof(double)*n2);
|
||||
sn=n2;
|
||||
grib_get_double_array(h2,"latitudes",lat2,&sn);
|
||||
grib_get_double_array(h2,"longitudes",lon2,&sn);
|
||||
grib_get_double_array(h2,"values",v2,&sn);
|
||||
|
||||
for (i=0;i<n;i++) {
|
||||
if ((j=idx(lat[i],lon[i],latFirst1,lonFirst1,latLast1,lonLast1,Ni1,di1,dj1)) >=0 ) {
|
||||
v[i]=v1[j];
|
||||
} else if ( (j=idx(lat[i],lon[i],latFirst2,lonFirst2,latLast2,lonLast2,Ni2,di2,dj2))>=0) {
|
||||
v[i]=v2[j];
|
||||
}
|
||||
}
|
||||
|
||||
grib_set_double_array(h,"values",v,n);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
int grib_tool_new_handle_action(grib_runtime_options* options, grib_handle* h) {
|
||||
int err=0;
|
||||
grib_handle* hm=0;
|
||||
char md5[200]={0,};
|
||||
char fname[210]={0,};
|
||||
size_t lmd5;
|
||||
|
||||
if (!hh) { hh=grib_handle_clone(h); return 0; }
|
||||
grib_get_string(h,"md5Product",md5,&lmd5);
|
||||
sprintf(fname,"_%s.orig.grib",md5);
|
||||
grib_write_message(h,fname,"a");
|
||||
|
||||
if ((hm=merge(h,hh))==NULL ) {
|
||||
grib_tools_write_message(options,hh);
|
||||
lmd5=sizeof(md5)/sizeof(*md5);
|
||||
grib_get_string(hh,"md5Product",md5,&lmd5);
|
||||
sprintf(fname,"_%s.merge.grib",md5);
|
||||
grib_write_message(hh,fname,"a");
|
||||
}
|
||||
grib_handle_delete(hh);
|
||||
hh = hm!=NULL ? hm : grib_handle_clone(h) ;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int grib_tool_skip_handle(grib_runtime_options* options, grib_handle* h) {
|
||||
grib_handle_delete(h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void grib_tool_print_key_values(grib_runtime_options* options,grib_handle* h) {
|
||||
grib_print_key_values(options,h);
|
||||
}
|
||||
|
||||
int grib_tool_finalise_action(grib_runtime_options* options) {
|
||||
grib_tools_write_message(options,hh);
|
||||
if (options->outfile->file) {
|
||||
fclose(options->outfile->file);
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue