vil_nitf2_field_functor.h
Go to the documentation of this file.
1 // vil_nitf2: Written by Harry Voorhees (hlv@) and Rob Radtke (rob@) of
2 // Stellar Science Ltd. Co. (stellarscience.com) for
3 // Air Force Research Laboratory, 2005.
4 
5 #ifndef VIL_NITF2_FIELD_FUNCTOR_H
6 #define VIL_NITF2_FIELD_FUNCTOR_H
7 
8 class vil_nitf2_field;
11 
12 #include <map>
13 #include <string>
14 #include <utility>
15 #include <vector>
17 #ifdef _MSC_VER
18 # include <vcl_msvc_warnings.h>
19 #endif
20 
21 //-----------------------------------------------------------------------------
22 //:
23 // \file
24 // \brief Functors used by NITF classes
25 //
26 // Base class for functors that define a function that takes a
27 // vil_nitf2_field_sequence and attempts to compute an "out" parameter of
28 // type T. The function also returns a bool that specifies whether the
29 // value could be computed.
30 //
31 // These functors are used to evaluate NITF field tags and invariably
32 // call vil_nitf2_field_sequence::get_value(). When calling this method,
33 // please be sure to set the argument ignore_extra_indexes to true.
34 // This will allow the functor to be used within a repeat loop
35 // and reference any preceding tag, inside or outside the repeat loop.
36 // For example, to define a field sequence like this:
37 // FIELD A;
38 // REPEAT i=1..N
39 // FIELD B(i)
40 // FIELD C(i) exists if B(i) > 0
41 // FIELD D(i) exists if A > 0
42 // the same conditional functor can be used in the definitions of fields
43 // C and D by simply providing the name of the appropriate tag. When
44 // the functor is evaluated, the current index (i) is used to fetch the
45 // tag. By calling get_value() with ignore_extra_indexes set to true,
46 // the value of A can be fetched without causing an error.
47 
48 template<typename T>
50 {
51  public:
52  virtual bool operator() (vil_nitf2_field_sequence* record,
53  const vil_nitf2_index_vector& indexes, T& out_value) = 0;
54  virtual ~vil_nitf2_field_functor() = default;
55 
56  // Virtual copy method
57  virtual vil_nitf2_field_functor<T>* copy() const = 0;
58 };
59 
60 //:
61 // Functor vil_nitf2_field_value defines a function that sets its out parameter
62 // to a value of a field from a field sequence. The function returns whether
63 // the field was found. The functor is instantiated with the field's tag.
64 // The field sequence is passed to the function.
65 //
66 // You can override any value by specifying an overrideMap. For example,
67 // if 0 was a special value that actually meant 1 but all other values
68 // (2, 3, 4...) actually meant when they were you could get that effect like this:
69 // <code>
70 // std::map< int, int > overrides;
71 // overrides.insert( std::make_pair( 0, 1 ) );
72 // new vil_nitf2_field_value( "FIELD_NAME", overrides );
73 // </code>
74 template<typename T>
76 {
77  public:
78  vil_nitf2_field_value(std::string tag) : tag(std::move(tag)) {}
79 
80  vil_nitf2_field_value(std::string tag, std::map<T, T> overrideMap )
81  : tag(std::move(tag)), overrides(std::move( overrideMap )) {}
82 
83  vil_nitf2_field_functor<T>* copy() const override {
84  return new vil_nitf2_field_value(tag, overrides); }
85 
87  const vil_nitf2_index_vector& indexes, T& value) override
88  {
89  bool success = record->get_value(tag, indexes, value, true);
90  if ( success ) {
91  //check to see if this value is overridden or not
92  typename std::map<T, T>::const_iterator it = overrides.find( value );
93  if ( it != overrides.end() ){
94  //found override, use it
95  value = (*it).second;
96  }
97  }
98  return success;
99  }
100 
101  private:
102  std::string tag;
103  std::map<T, T> overrides;
104 };
105 
106 //:
107 // Functor vil_nitf2_multiply_field_values defines a function that sets its out
108 // parameter to the product of the values of two fields. The predicate
109 // returns true iff both fields are found or the arg 'use_zero_if_tag_not_found';
110 // in the latter case, the out parameter is set to 0.
111 //
113 {
114  public:
116  std::string tag_2,
117  bool use_zero_if_tag_not_found = false)
118  : tag_1(std::move(tag_1)),
119  tag_2(std::move(tag_2)),
121 
122  vil_nitf2_field_functor<int>* copy() const override {
125  }
126 
128  const vil_nitf2_index_vector& indexes, int& value) override;
129 
130  private:
131  std::string tag_1;
132  std::string tag_2;
134 };
135 
136 //:
137 // Functor vil_nitf2_max_field_value_plus_offset_and_threshold defines a
138 // function that sets its out parameter to either the value of a specified
139 // field plus an offset, or a specified minimum value, whichever is greater.
140 // The function returns whether the field was found.
141 //
143 {
144  public:
146  std::string tag, int offset, int min_threshold = 0, int tag_factor = 1 )
148 
149  vil_nitf2_field_functor<int>* copy() const override {
152 
154  const vil_nitf2_index_vector& indexes, int& value) override;
155 
156  private:
157  std::string tag;
158  int offset;
161 };
162 
163 //:
164 // Functor vil_nitf2_field_value_greater_than defines a comparison predicate that
165 // sets its out parameter to true if a specified field from a field
166 // sequence is found and its value is greater than a specified threshold.
167 // The predicate returns whether the field was found.
168 //
169 template<typename T>
171 {
172  public:
174  : tag(std::move(tag)), threshold(threshold) {}
175 
178 
180  const vil_nitf2_index_vector& indexes, bool& result) override {
181  T value;
182  if (record->get_value(tag, indexes, value, true)) {
183  result = value > threshold;
184  return true;
185  }
186  else {
187  return false;
188  }
189  }
190  private:
191  std::string tag;
193 };
194 
195 //:
196 // Functor vil_nitf2_field_specified defines a comparison predicate that sets
197 // its out parameter to true iff the specified field is not blank.
198 //
200 {
201  public:
202  vil_nitf2_field_specified(std::string tag) : tag(std::move(tag)) {}
203 
205  return new vil_nitf2_field_specified(tag); }
206 
208  const vil_nitf2_index_vector& indexes, bool& result) override;
209 
210  private:
211  std::string tag;
212 };
213 
214 //:
215 // Functor vil_nitf2_field_value_one_of defines a predicate that sets its out
216 // parameter to true iff the value of the specified tag equals one of
217 // the elements of a std::vector of acceptable values.
218 //
219 template<typename T>
221 {
222  public:
223  /// Constructor to specify a std::vector of acceptable values
225  : tag(std::move(tag)), acceptable_values(std::move(acceptable_values)) {}
226 
227  /// Constructor to specify only one acceptable value
228  vil_nitf2_field_value_one_of(std::string tag, T acceptable_value)
229  : tag(std::move(tag)), acceptable_values(1, acceptable_value) {}
230 
233 
235  const vil_nitf2_index_vector& indexes, bool& result) override
236  {
237  result = false;
238  T val;
239  if (record->get_value(tag, indexes, val, true)) {
240  typename std::vector<T>::iterator it;
241  for (it = acceptable_values.begin(); it != acceptable_values.end(); ++it) {
242  if ((*it) == val) {
243  result = true;
244  break;
245  }
246  }
247  return true;
248  }
249  // Field not defined
250  return false;
251  }
252 
253  protected:
254  std::string tag;
255  std::vector<T> acceptable_values;
256 };
257 
258 //:
259 // Functor vil_nitf2_choose_field_value defines a function that sets its out
260 // parameter to a value of one of two fields of a field sequence. The
261 // field chosen is determined by the evaluating the functor passed as
262 // argument 'choose_tag_1_predicate': tag_1 is chosen if it evaluates to true;
263 // tag_2, otherwise.
264 //
265 template<typename T>
267 {
268  public:
269  /// Constructor. I take ownership of inDecider.
270  vil_nitf2_choose_field_value(std::string tag_1, std::string tag_2,
272  : tag_1(std::move(tag_1)), tag_2(std::move(tag_2)), choose_tag_1_predicate(choose_tag_1_predicate) {}
273 
274  vil_nitf2_field_functor<T>* copy() const override {
275  return new vil_nitf2_choose_field_value(
277 
280  }
281 
283  const vil_nitf2_index_vector& indexes, T& value) override {
284  bool choose_tag_1;
285  if ((*choose_tag_1_predicate)(record, indexes, choose_tag_1)) {
286  if (choose_tag_1) return record->get_value(tag_1, indexes, value, true);
287  else return record->get_value(tag_2, indexes, value, true);
288  }
289  else return false;
290  }
291  private:
292  std::string tag_1;
293  std::string tag_2;
295 };
296 
297 // Functor vil_nitf2_constant_functor defines a function that sets its
298 // output value to a constant that does not depend on the field sequence
299 // passed to it.
300 //
301 template<typename T>
303 {
304  public:
305  vil_nitf2_constant_functor(T value) : value_(value) {}
306 
307  vil_nitf2_constant_functor* copy() const override {
309  }
310 
311  ~vil_nitf2_constant_functor() override = default;
312 
314  const vil_nitf2_index_vector& /*indexes*/, T& value) override {
315  value = value_;
316  return true;
317  }
318 
319  private:
321 };
322 
323 #endif // VIL_NITF2_FIELD_FUNCTOR_H
Functor vil_nitf2_field_value_one_of defines a predicate that sets its out parameter to true iff the ...
Functor vil_nitf2_max_field_value_plus_offset_and_threshold defines a function that sets its out para...
Functor vil_nitf2_field_value defines a function that sets its out parameter to a value of a field fr...
vil_nitf2_field_functor< int > * copy() const override
vil_nitf2_field_functor< int > * copy() const override
bool operator()(vil_nitf2_field_sequence *, const vil_nitf2_index_vector &, T &value) override
vil_nitf2_field_value(std::string tag, std::map< T, T > overrideMap)
vil_nitf2_field_functor< bool > * copy() const override
vil_nitf2_field_value_greater_than(std::string tag, T threshold)
vil_nitf2_field_value_one_of(std::string tag, T acceptable_value)
Constructor to specify only one acceptable value.
bool operator()(vil_nitf2_field_sequence *record, const vil_nitf2_index_vector &indexes, bool &result) override
virtual bool operator()(vil_nitf2_field_sequence *record, const vil_nitf2_index_vector &indexes, T &out_value)=0
virtual ~vil_nitf2_field_functor()=default
bool operator()(vil_nitf2_field_sequence *record, const vil_nitf2_index_vector &indexes, int &value) override
vil_nitf2_field_functor< T > * copy() const override
bool operator()(vil_nitf2_field_sequence *record, const vil_nitf2_index_vector &indexes, bool &result) override
virtual vil_nitf2_field_functor< T > * copy() const =0
vil_nitf2_field_functor< bool > * copy() const override
bool operator()(vil_nitf2_field_sequence *record, const vil_nitf2_index_vector &indexes, T &value) override
vil_nitf2_multiply_field_values(std::string tag_1, std::string tag_2, bool use_zero_if_tag_not_found=false)
~vil_nitf2_constant_functor() override=default
vil_nitf2_field_value(std::string tag)
vil_nitf2_field_functor< T > * copy() const override
vil_nitf2_field_functor< bool > * choose_tag_1_predicate
bool operator()(vil_nitf2_field_sequence *record, const vil_nitf2_index_vector &indexes, T &value) override
vil_nitf2_constant_functor * copy() const override
bool operator()(vil_nitf2_field_sequence *record, const vil_nitf2_index_vector &indexes, int &value) override
Functor vil_nitf2_choose_field_value defines a function that sets its out parameter to a value of one...
vil_nitf2_field_specified(std::string tag)
vil_nitf2_max_field_value_plus_offset_and_threshold(std::string tag, int offset, int min_threshold=0, int tag_factor=1)
vil_nitf2_field_value_one_of(std::string tag, std::vector< T > acceptable_values)
Constructor to specify a std::vector of acceptable values.
bool operator()(vil_nitf2_field_sequence *record, const vil_nitf2_index_vector &indexes, bool &result) override
bool get_value(std::string tag, int &out_value) const
Functor vil_nitf2_multiply_field_values defines a function that sets its out parameter to the product...
Functor vil_nitf2_field_value_greater_than defines a comparison predicate that sets its out parameter...
vil_nitf2_field_functor< bool > * copy() const override
vil_nitf2_choose_field_value(std::string tag_1, std::string tag_2, vil_nitf2_field_functor< bool > *choose_tag_1_predicate)
Constructor. I take ownership of inDecider.
Functor vil_nitf2_field_specified defines a comparison predicate that sets its out parameter to true ...