Orfeo Toolbox  3.16
otbOGRFieldWrapper.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: ORFEO Toolbox
4  Language: C++
5  Date: $Date$
6  Version: $Revision$
7 
8 
9  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
10  See OTBCopyright.txt for details.
11 
12 
13  This software is distributed WITHOUT ANY WARRANTY; without even
14  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  PURPOSE. See the above copyright notices for more information.
16 
17 =========================================================================*/
18 
19 #ifndef __otbOGRFieldWrapper_txx
20 #define __otbOGRFieldWrapper_txx
21 
22 /*===========================================================================*/
23 /*===============================[ Includes ]================================*/
24 /*===========================================================================*/
25 #include "otbOGRFieldWrapper.h"
26 #include <cassert>
27 #include <vector>
28 #include <boost/mpl/map.hpp>
29 #include <boost/mpl/vector.hpp>
30 #include <boost/mpl/pair.hpp>
31 #include <boost/mpl/int.hpp>
32 #include <boost/mpl/at.hpp>
33 #include <boost/mpl/assert.hpp>
34 // #include <boost/mpl/print.hpp>
35 
36 #include <boost/static_assert.hpp>
37 #include <boost/range/size.hpp>
38 #include <boost/type_traits/is_same.hpp>
39 // #include "boost/type_traits/is_array.hpp"
40 #include "boost/type_traits/is_contiguous.h" // from OTB actually
41 
42 #include "ogr_feature.h" // OGRFeature::*field_getters
43 #include "cpl_string.h" // CSLCount
44 #include "otbOGRHelpers.h"
45 
46 
47 /*===========================================================================*/
48 /*================[ Associations C++ types -> OGR functions ]================*/
49 /*===========================================================================*/
50 
51 namespace otb { namespace ogr {
61 namespace internal { // namespace internal
62 using namespace boost::mpl;
63 
71 typedef boost::mpl::map
72  < pair<int , int_<OFTInteger> >
73  , pair<std::vector<int> , int_<OFTIntegerList> >
74  , pair<double , int_<OFTReal> >
75  , pair<std::vector<double> , int_<OFTRealList> >
76  , pair<std::string , int_<OFTString> >
77  , pair<char* , int_<OFTString> >
78  , pair<char const* , int_<OFTString> >
79  , pair<std::vector<std::string>, int_<OFTStringList> >
80  // OFTBinary
81  // OFTDate
82  // OFTTime
83  // OFTDateTime
85 
99 template
100  < typename T
101  , T ( OGRFeature::*ptr_to_function )(int)
102  , typename FinalReturnType = T
104  {
105  public:
106  static FinalReturnType call(OGRFeature &f, int index)
107  {
108  return (f.*ptr_to_function)(index);
109  }
110  };
111 
124 template
125  < typename FinalReturnType = std::vector<std::string>
127  {
128  public:
129  static FinalReturnType call(OGRFeature &f, int index)
130  {
131  char ** sl = f.GetFieldAsStringList(index);
132  FinalReturnType res(sl, sl+CSLCount(sl));
133  return res;
134  }
135  };
136 
149 template
150  < typename T
151  , void ( OGRFeature::*ptr_to_function )(int, T value)
152  , typename ActualParamType = T
154  {
155  public:
156  static void call(OGRFeature &f, int index, T const& value)
157  {
158  (f.*ptr_to_function)(index, value);
159  }
160  };
161 
175 template
176  < typename T
177  , T const* ( OGRFeature::*ptr_to_function )(int, int*)
178  , typename FinalReturnType = std::vector<T>
180  {
181  public:
182  static FinalReturnType call(OGRFeature &f, int index)
183  {
184  int nb = 0;
185  T const* raw_container = (f.*ptr_to_function)(index, &nb);
186  const FinalReturnType res(raw_container+0, raw_container+nb);
187  return res;
188  }
189  };
190 
191 /*===========================================================================*/
202 template
203  < typename T
204  , void ( OGRFeature::*ptr_to_function )(int, int, T*) // not const-correct
205  , typename ActualParamType = std::vector<T>
206  , bool Is_contiguous = boost::is_contiguous<ActualParamType>::value
208 
211 template
212  < typename T
213  , void ( OGRFeature::*ptr_to_function )(int, int, T*) // not const-correct
214  , typename ActualParamType
216  {
217  public:
218  static void call(OGRFeature &f, int index, ActualParamType const& container)
219  {
220  const int nb = boost::size(container);
221  (f.*ptr_to_function)(index, nb, const_cast <T*>(&container[0]));
222  }
223  };
224 
227 template
228  < typename T
229  , void ( OGRFeature::*ptr_to_function )(int, int, T*) // not const-correct
230  , typename ActualParamType
232  {
233  public:
234  static void call(OGRFeature &f, int index, ActualParamType const& container)
235  {
236  const int nb = boost::size(container);
237  std::vector<T> v(boost::begin(container), boost::end(container));
238  (f.*ptr_to_function)(index, nb, &v[0]);
239  }
240  };
241 
253 template
254  < typename ActualParamType
256  {
257  public:
258  static void call(OGRFeature &f, int index, ActualParamType const& container)
259  {
260  f.SetField(index, StringListConverter(container).to_ogr());
261  }
262  };
263 
277 template
278  < typename T
279  , void ( OGRFeature::*ptr_to_function )(int, int, T*) // not const-correct
280  , typename ActualParamType = std::vector<T>
282  {
283  public:
284  static void call(OGRFeature &f, int index, ActualParamType const& container)
285  {
287  T
288  ,ptr_to_function
289  ,ActualParamType
291  >::call(f, index, container);
292  }
293  };
294 
301 typedef map
302  < pair<int_<OFTInteger>, MemberGetterPtr<int, &OGRFeature::GetFieldAsInteger> >
303  , pair<int_<OFTIntegerList>, MemberContainerGetterPtr<int, &OGRFeature::GetFieldAsIntegerList> >
304  , pair<int_<OFTReal>, MemberGetterPtr<double, &OGRFeature::GetFieldAsDouble> >
305  , pair<int_<OFTRealList>, MemberContainerGetterPtr<double, &OGRFeature::GetFieldAsDoubleList> >
306  , pair<int_<OFTString>, MemberGetterPtr<char const*, &OGRFeature::GetFieldAsString, std::string> >
307  , pair<int_<OFTStringList>, StringListMemberGetterPtr<std::vector<std::string> > >
309 
316 typedef map
317  < pair<int_<OFTInteger>, MemberSetterPtr<int, &OGRFeature::SetField> >
318  , pair<int_<OFTIntegerList>, MemberContainerSetterPtr<int, &OGRFeature::SetField> >
319  , pair<int_<OFTReal>, MemberSetterPtr<double, &OGRFeature::SetField> >
321  , pair<int_<OFTString>, MemberSetterPtr<char const*, &OGRFeature::SetField/*, std::string*/> >
322  , pair<int_<OFTStringList>, StringListMemberSetterPtr<std::vector<std::string> > >
324 
334 template <typename T> struct CppToOGRConverter_trait
335  {
336  typedef T type;
337  static T const& convert(T const& value) { return value; }
338  };
339 
343 template <typename T, std::size_t N> struct CppToOGRConverter_trait<T[N]>
344  {
345  typedef T* type;
346  static T const* convert(const T value[N]) { return &value[0]; }
347  };
348 
352 template <> struct CppToOGRConverter_trait<std::string>
353  {
354  typedef char* type;
355  static char const* convert(std::string const& value) { return value.c_str(); }
356  };
357 
358 } // namespace internal
359 } } // end namespace otb::ogr
360 
361 /*===========================================================================*/
362 /*=======================[ otb::ogr::Field functions ]=======================*/
363 /*===========================================================================*/
364 
365 inline
367 {
368  assert(m_Feature && "OGR Fields must be associated to a valid feature");
369  assert(int(m_index) < m_Feature->GetFieldCount() && "Out-of-range index for a OGR field");
370  assert(m_Feature->GetFieldDefnRef(m_index) && "No definition available for the OGR field");
371 }
372 
373 template <typename T>
374 inline
375 void otb::ogr::Field::SetValue(T const& value)
376 {
377  CheckInvariants();
378  typedef internal::CppToOGRConverter_trait<T> Converter;
379  typedef typename Converter::type InterfaceType;
380  // uncomment the next line to debug the InterfaceType computed
381  // boost::mpl::print<typename internal::CppToOGRConverter_trait<T>::type> interface_type; (void) interface_type;
382  BOOST_MPL_ASSERT_MSG(!boost::is_array<InterfaceType>::value, InterFaceType_Cant_Be_An_array, (T, InterfaceType));
383  typedef typename boost::mpl::at<internal::FieldType_Map, InterfaceType>::type Kind;
384  BOOST_MPL_ASSERT_MSG(!(boost::is_same<Kind, boost::mpl::void_>::value), UNEXPECTED_KIND_TYPE, (T, InterfaceType, Kind));
385  const int VALUE = Kind::value;
386  assert(m_Definition.GetType() == VALUE && "OGR field type mismatches the type of new field value");
387  typedef typename boost::mpl::at<internal::FieldSetters_Map, Kind>::type SetterType;
388  // If you experience a static assertion failure in the line below, it means
389  // the type of the parameter is not supported to set a field.
390  BOOST_MPL_ASSERT_NOT((boost::is_same<SetterType, boost::mpl::void_>));
391  SetterType::call(*m_Feature, m_index, Converter::convert(value));
392 }
393 
394 template <typename T>
395 inline
397 {
398  CheckInvariants();
399  assert(HasBeenSet() && "Cannot access the value of a field that hasn't been set");
400  typedef typename boost::mpl::at<internal::FieldType_Map, T>::type Kind;
401  const int VALUE = Kind::value;
402  BOOST_STATIC_ASSERT(!(boost::is_same<Kind, boost::mpl::void_>::value));
403  assert(m_Definition.GetType() == VALUE && "OGR field type mismatches the type of requested field value");
404  typedef typename boost::mpl::at<internal::FieldGetters_Map, Kind>::type GetterType;
405  // If you experience a static assertion failure in the line below, it means
406  // the field cannot be extracted into the type requested.
407  BOOST_STATIC_ASSERT(!(boost::is_same<GetterType, boost::mpl::void_>::value));
408  return GetterType::call(*m_Feature, m_index);
409 }
410 
411 inline
413  std::ostream& os, itk::Indent indent) const
414 {
415  CheckInvariants();
416  return UncheckedPrintSelf(os, indent);
417 }
418 
419 inline
421 {
422  CheckInvariants();
423  return UncheckedHasBeenSet();
424 }
425 
426 inline
428 {
429  CheckInvariants();
430  UncheckedUnset();
431 }
432 
433 inline
435 {
436  CheckInvariants();
437  f.CheckInvariants();
438  assert(f.GetType() == this->GetType() && "Cannot assign from a field that doesn't have the same definition");
439  // We can't assume the following as sometimes field names are altered by the
440  // datasource driver; for instance, shp driver truncates field names to 8
441  // characters.
442  // assert(f.GetDefinition() == this->GetDefinition() && "Cannot assign from a field that doesn't have the same definition");
443  UncheckedAssign(f);
444  CheckInvariants();
445 }
446 
447 inline
448 OGRField & otb::ogr::Field::ogr() const
449 {
450  return const_cast <Field*>(this)->ogr();
451 }
452 
453 inline
455 {
456  CheckInvariants();
457  OGRField * f = m_Feature->GetRawFieldRef(m_index);
458  assert(f && "The field obtained shall not be null");
459  return *f;
460 }
461 
462 #endif // __otbOGRFieldWrapper_txx

Generated at Sun May 19 2013 00:42:31 for Orfeo Toolbox with doxygen 1.8.3.1