1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/***************************** LICENSE START ***********************************
Copyright 2012 ECMWF and INPE. This software is distributed under the terms
of the Apache License version 2.0. In applying this license, ECMWF does not
waive the privileges and immunities granted to it by virtue of its status as
an Intergovernmental Organization or submit itself to any jurisdiction.
***************************** LICENSE END *************************************/
#include <MvRequestUtil.hpp>
#include <fdyntime.h>
#include "MvGribDecoder.h"
#include "MatchingInfo.h"
#include "ObjectList.h"
// =====================================================
// class GribDecoderFactory - builds decoders
//
class GribDecoderFactory : public DecoderFactory
{
// Virtual Constructor - Builds a new GribDecoder
virtual Decoder* Build ( const MvRequest& inRequest )
{ return new GribDecoder ( inRequest ); }
public:
GribDecoderFactory() : DecoderFactory("GribDecoder") {}
};
static GribDecoderFactory gribDecoderFactoryInstance;
//=======================================================
//
// Methods for the GribDecoder class
//
GribDecoder::GribDecoder( const MvRequest& dataUnitRequest ):
Decoder(dataUnitRequest),
fieldSet_(dataUnitRequest),
fieldSetIterator_(fieldSet_)
{
// Empty
}
GribDecoder::~GribDecoder()
{
// Empty
}
// Read Next Data
//
// -- Goes to the next data and returns the offset (data size)
// -- Grib decoder only reads one field
bool
GribDecoder::ReadNextData ()
{
currentField_ = fieldSetIterator_(); // Read next data
if ( !currentField_ )
return false;
// Expand the field
// MvFieldExpander expand(currentField);
metadataRequest_ = currentField_.getRequest();
// Get Offset
offset_ = currentField_.getOffset();
return true;
}
// Create MatchingInfo
// Retrieve the matching request
MatchingInfo
GribDecoder::CreateMatchingInfo ()
{
const char* ident = metadataRequest_("IDENT");
MvRequest matchingRequest ("MATCHING_INFO");
matchingRequest ( "PARAM" ) = metadataRequest_("PARAM");
SetIfValue ( matchingRequest, "LEVEL", metadataRequest_("LEVELIST") );
// XXX this might not be necessary since we're not interested in
// IDENT for identifying satellite images anymore.
if (ident != NULL)
matchingRequest ("IDENT") = ident;
// For hindcast, data, we use HDATE, not DATE, so check this first
long date = (long)metadataRequest_("HDATE");
if (date == 0) date = (long)metadataRequest_("DATE");
TDynamicTime matchTime(date, (long)metadataRequest_("TIME"));
// Take the step into account when generating the matching time
matchTime.ChangeByHours( MvField::stepRangeDecoder(metadataRequest_("STEP")) );
char buf[50];
sprintf(buf,"%ddd",matchTime.GetYear(),matchTime.GetMonth(), matchTime.GetDay() );
matchingRequest("DATE") = buf;
sprintf(buf,"dd",matchTime.GetHour(),matchTime.GetMin() );
matchingRequest("TIME") = buf;
// we will later need to decide whether to apply automatic scaling or not
//ir matchingRequest("DERIVED") = metadataRequest_("DERIVED");
// Is it an image field?
const char* repres = metadataRequest_("REPRES");
if ( ObjectList::IsImage( repres ) )
matchingRequest( "DATA_TYPE" ) = "IMAGE";
else
{
// Get parameter name
const size_t cMaxBuf = 99;
char acc0[cMaxBuf+1];
size_t nsize = cMaxBuf;
field* ff = currentField_.libmars_field();
grib_get_string( ff->handle, "shortName", acc0, &nsize );
matchingRequest ( "PARAM" ) = acc0;
matchingRequest( "DATA_TYPE" ) = "GRIB";
// Has this parameter a companion?
string pair,mode;
bool first_companion;
ObjectList::GetCompanion( string(acc0), pair, mode, first_companion );
if ( pair != "no_pair" )
{
matchingRequest ( "MY_COMPANION" ) = pair.c_str();
matchingRequest ( "FIRST_COMPANION" ) = first_companion;
if ( !mode.empty() )
matchingRequest ( "WIND_MODE" ) = mode.c_str();
}
}
return MatchingInfo( matchingRequest );
}
|