core/vil/file_formats/vil_nitf2_field_functor.h

Go to the documentation of this file.
00001 // vil_nitf2: Written by Harry Voorhees (hlv@) and Rob Radtke (rob@) of
00002 // Stellar Science Ltd. Co. (stellarscience.com) for
00003 // Air Force Research Laboratory, 2005.
00004 
00005 #ifndef VIL_NITF2_FIELD_FUNCTOR_H
00006 #define VIL_NITF2_FIELD_FUNCTOR_H
00007 
00008 class vil_nitf2_field;
00009 class vil_nitf2_enum_values;
00010 class vil_nitf2_index_vector;
00011 
00012 #include <vcl_string.h>
00013 #include <vcl_vector.h>
00014 #include <vcl_map.h>
00015 #include "vil_nitf2_field_sequence.h"
00016 
00017 //-----------------------------------------------------------------------------
00018 //:
00019 // \file
00020 // \brief Functors used by NITF classes
00021 //
00022 // Base class for functors that define a function that takes a
00023 // vil_nitf2_field_sequence and attempts to compute an "out" parameter of
00024 // type T. The function also returns a bool that specifies whether the
00025 // value could be computed.
00026 //
00027 // These functors are used to evaluate NITF field tags and invariably
00028 // call vil_nitf2_field_sequence::get_value(). When calling this method,
00029 // please be sure to set the argument ignore_extra_indexes to true.
00030 // This will allow the functor to be used within a repeat loop
00031 // and reference any preceding tag, inside or outside the repeat loop.
00032 // For exampe, to define a field sequence like this:
00033 //   FIELD A;
00034 //   REPEAT i=1..N
00035 //     FIELD B(i)
00036 //     FIELD C(i) exists if B(i) > 0
00037 //     FIELD D(i) exists if A > 0
00038 // the same conditional functor can be used in the definitions of fields
00039 // C and D by simply providing the name of the appropriate tag.  When
00040 // the functor is evaluated, the current index (i) is used to fetch the
00041 // tag. By calling get_value() with ignore_extra_indexes set to true,
00042 // the value of A can be fetched without causing an error.
00043 
00044 template<typename T>
00045 class vil_nitf2_field_functor
00046 {
00047  public:
00048   virtual bool operator() (vil_nitf2_field_sequence* record,
00049                            const vil_nitf2_index_vector& indexes, T& out_value) = 0;
00050   virtual ~vil_nitf2_field_functor() {}
00051 
00052   // Virtual copy method
00053   virtual vil_nitf2_field_functor<T>* copy() const = 0;
00054 };
00055 
00056 //:
00057 // Functor vil_nitf2_field_value defines a function that sets its out parameter
00058 // to a value of a field from a field sequence. The function returns whether
00059 // the field was found. The functor is instantiated with the field's tag.
00060 // The field sequence is passed to the function.
00061 //
00062 // You can override any value by specifying an overrideMap.  For example,
00063 // if 0 was a special value that actually meant 1 but all other values 
00064 // (2, 3, 4...) actually meant when they were you could get that effect like this:
00065 // <code>
00066 // vcl_map< int, int > overrides;
00067 // overrides.insert( vcl_make_pair( 0, 1 ) );
00068 // new vil_nitf2_field_value( "FIELD_NAME", overrides );
00069 // </code>
00070 template<typename T>
00071 class vil_nitf2_field_value : public vil_nitf2_field_functor<T>
00072 {
00073  public:
00074   vil_nitf2_field_value(vcl_string tag) : tag(tag) {}
00075 
00076   vil_nitf2_field_value(vcl_string tag, vcl_map<T, T> overrideMap ) 
00077     : tag(tag), overrides( overrideMap ) {}
00078 
00079   virtual vil_nitf2_field_functor<T>* copy() const {
00080     return new vil_nitf2_field_value(tag, overrides); }
00081 
00082   bool operator() (vil_nitf2_field_sequence* record,
00083                    const vil_nitf2_index_vector& indexes, T& value)
00084   {
00085     bool success = record->get_value(tag, indexes, value, true);
00086     if( success ) {
00087       //check to see if this value is overridden or not
00088       typename vcl_map<T, T>::const_iterator it = overrides.find( value );
00089       if( it != overrides.end() ){
00090         //found override, use it
00091         value = (*it).second;
00092       }
00093     }
00094     return success;
00095   }
00096 
00097  private:
00098   vcl_string tag;
00099   vcl_map<T, T> overrides;
00100 };
00101 
00102 //:
00103 // Functor vil_nitf2_multiply_field_values defines a function that sets its out
00104 // parameter to the product of the values of two fields. The predicate
00105 // returns true iff both fields are found or the arg 'use_zero_if_tag_not_found';
00106 // in the latter case, the out parameter is set to 0.
00107 //
00108 class vil_nitf2_multiply_field_values : public vil_nitf2_field_functor<int>
00109 {
00110  public:
00111   vil_nitf2_multiply_field_values(const vcl_string& tag_1,
00112                                   const vcl_string& tag_2,
00113                                   bool use_zero_if_tag_not_found = false)
00114     : tag_1(tag_1),
00115       tag_2(tag_2),
00116       use_zero_if_tag_not_found(use_zero_if_tag_not_found) {}
00117 
00118   vil_nitf2_field_functor<int>* copy() const {
00119     return new vil_nitf2_multiply_field_values(
00120       tag_1, tag_2, use_zero_if_tag_not_found); 
00121   }
00122 
00123   bool operator() (vil_nitf2_field_sequence* record,
00124                    const vil_nitf2_index_vector& indexes, int& value);
00125 
00126  private:
00127   vcl_string tag_1;
00128   vcl_string tag_2;
00129   bool use_zero_if_tag_not_found;
00130 };
00131 
00132 //:
00133 // Functor vil_nitf2_max_field_value_plus_offset_and_threshold defines a
00134 // function that sets its out parameter to either the value of a specified
00135 // field plus an offset, or a specified minimum value, whichever is greater.
00136 // The function returns whether the field was found.
00137 //
00138 class vil_nitf2_max_field_value_plus_offset_and_threshold : public vil_nitf2_field_functor<int>
00139 {
00140  public:
00141   vil_nitf2_max_field_value_plus_offset_and_threshold(
00142     vcl_string tag, int offset, int min_threshold = 0, int tag_factor = 1 )
00143     : tag(tag), offset(offset), min_threshold(min_threshold), tag_factor( tag_factor ) {}
00144 
00145   vil_nitf2_field_functor<int>* copy() const {
00146     return new vil_nitf2_max_field_value_plus_offset_and_threshold(
00147       tag, offset, min_threshold, tag_factor); }
00148   
00149   bool operator() (vil_nitf2_field_sequence* record,
00150                    const vil_nitf2_index_vector& indexes, int& value);
00151 
00152  private:
00153   vcl_string tag;
00154   int offset;
00155   int min_threshold;
00156   int tag_factor;
00157 };
00158 
00159 //:
00160 // Functor vil_nitf2_field_value_greater_than defines a comparison predicate that
00161 // sets its out parameter to true if a specified field from a field
00162 // sequence is found and its value is greater than a specified threshold.
00163 // The predicate returns whether the field was found.
00164 //
00165 template<typename T>
00166 class vil_nitf2_field_value_greater_than: public vil_nitf2_field_functor<bool>
00167 {
00168  public:
00169   vil_nitf2_field_value_greater_than(vcl_string tag, T threshold)
00170     : tag(tag), threshold(threshold) {}
00171 
00172   vil_nitf2_field_functor<bool>* copy() const {
00173     return new vil_nitf2_field_value_greater_than(tag, threshold); }
00174     
00175   bool operator() (vil_nitf2_field_sequence* record,
00176                    const vil_nitf2_index_vector& indexes, bool& result) {
00177     T value;
00178     if (record->get_value(tag, indexes, value, true)) {
00179       result = value > threshold;
00180       return true;
00181     } else {
00182       return false;
00183     }
00184   }
00185  private:
00186   vcl_string tag;
00187   T threshold;
00188 };
00189 
00190 //:
00191 // Functor vil_nitf2_field_specified defines a comparison predicate that sets
00192 // its out parameter to true iff the specified field is not blank.
00193 //
00194 class vil_nitf2_field_specified: public vil_nitf2_field_functor<bool>
00195 {
00196  public:
00197   vil_nitf2_field_specified(vcl_string tag) : tag(tag) {}
00198 
00199   vil_nitf2_field_functor<bool>* copy() const {
00200     return new vil_nitf2_field_specified(tag); }
00201 
00202   bool operator() (vil_nitf2_field_sequence* record,
00203                    const vil_nitf2_index_vector& indexes, bool& result);
00204 
00205  private:
00206   vcl_string tag;
00207 };
00208 
00209 //:
00210 // Functor vil_nitf2_field_value_one_of defines a predicate that sets its out
00211 // parameter to true iff the value of the specified tag equals one of
00212 // the elements of a vcl_vector of acceptable values.
00213 //
00214 template<typename T>
00215 class vil_nitf2_field_value_one_of: public vil_nitf2_field_functor<bool>
00216 {
00217  public:
00218   /// Constructor to specify a vcl_vector of acceptable values
00219   vil_nitf2_field_value_one_of(vcl_string tag, vcl_vector<T> acceptable_values)
00220     : tag(tag), acceptable_values(acceptable_values) {};
00221 
00222   /// Constructor to specify only one acceptable value
00223   vil_nitf2_field_value_one_of(vcl_string tag, T acceptable_value)
00224     : tag(tag), acceptable_values(1, acceptable_value) {}
00225 
00226   vil_nitf2_field_functor<bool>* copy() const {
00227     return new vil_nitf2_field_value_one_of(tag, acceptable_values); }
00228 
00229   bool operator() (vil_nitf2_field_sequence* record,
00230                    const vil_nitf2_index_vector& indexes, bool& result)
00231   {
00232     result = false;
00233     T val;
00234     if (record->get_value(tag, indexes, val, true)) {
00235       typename vcl_vector<T>::iterator it;
00236       for (it = acceptable_values.begin(); it != acceptable_values.end(); ++it) {
00237         if ((*it) == val) {
00238           result = true;
00239           break;
00240         }
00241       }
00242       return true;
00243     }
00244     // Field not defined
00245     return false;
00246   }
00247 
00248  protected:
00249   vcl_string tag;
00250   vcl_vector<T> acceptable_values;
00251 };
00252 
00253 //:
00254 // Functor vil_nitf2_choose_field_value defines a function that sets its out
00255 // parameter to a value of one of two fields of a field sequence. The
00256 // field chosen is determined by the evaluating the functor passed as
00257 // argument 'choose_tag_1_predicate': tag_1 is chosen if it evaluates to true;
00258 // tag_2, otherwise.
00259 //
00260 template<typename T>
00261 class vil_nitf2_choose_field_value : public vil_nitf2_field_functor<T>
00262 {
00263  public:
00264   /// Constructor. I take ownership of inDecider.
00265   vil_nitf2_choose_field_value(const vcl_string& tag_1, const vcl_string& tag_2,
00266                                vil_nitf2_field_functor<bool>* choose_tag_1_predicate)
00267     : tag_1(tag_1), tag_2(tag_2), choose_tag_1_predicate(choose_tag_1_predicate) {}
00268 
00269   vil_nitf2_field_functor<T>* copy() const {
00270     return new vil_nitf2_choose_field_value(
00271       tag_1, tag_2, choose_tag_1_predicate->copy()); }
00272     
00273   virtual ~vil_nitf2_choose_field_value() {
00274     if (choose_tag_1_predicate) delete choose_tag_1_predicate;
00275   }
00276 
00277   bool operator() (vil_nitf2_field_sequence* record,
00278                    const vil_nitf2_index_vector& indexes, T& value) {
00279     bool choose_tag_1;
00280     if ((*choose_tag_1_predicate)(record, indexes, choose_tag_1)) {
00281       if (choose_tag_1) return record->get_value(tag_1, indexes, value, true);
00282       else return record->get_value(tag_2, indexes, value, true);
00283     } else return false;
00284   }
00285  private:
00286   vcl_string tag_1;
00287   vcl_string tag_2;
00288   vil_nitf2_field_functor<bool>* choose_tag_1_predicate;
00289 };
00290 
00291 // Functor vil_nitf2_constant_functor defines a function that sets its
00292 // output value to a constant that does not depend on the field sequence
00293 // passed to it.
00294 //
00295 template<typename T>
00296 class vil_nitf2_constant_functor : public vil_nitf2_field_functor<T>
00297 {
00298 public:
00299   vil_nitf2_constant_functor(T value) : value_(value) {}
00300 
00301   virtual vil_nitf2_constant_functor* copy() const {
00302     return new vil_nitf2_constant_functor(value_);
00303   }
00304 
00305   virtual ~vil_nitf2_constant_functor() {}
00306 
00307   bool operator() (vil_nitf2_field_sequence* /*record*/,
00308                   const vil_nitf2_index_vector& /*indexes*/, T& value) {
00309     value = value_;
00310     return true;
00311   }
00312 
00313 private:
00314   T value_;
00315 }; 
00316 
00317 #endif // VIL_NITF2_FIELD_FUNCTOR_H

Generated on Sat Nov 22 05:07:51 2008 for core/vil by  doxygen 1.5.1