diff --git a/Code/Common/otbJoinContainer.h b/Code/Common/otbJoinContainer.h new file mode 100644 index 0000000000000000000000000000000000000000..fd315afa9d265cb03fc23fee7d467519417a2505 --- /dev/null +++ b/Code/Common/otbJoinContainer.h @@ -0,0 +1,64 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef __otbJoinContainer_h +#define __otbJoinContainer_h + +// #include <iosfwd> +#include <string> + +#include <ostream> +// #include <boost/range/iterator.hpp> +#include <boost/range/begin.hpp> +#include <boost/range/end.hpp> +#include <boost/range/empty.hpp> +namespace otb +{ + /**\ingroup Common + * Joins elements from a range into a stream. + * \tparam TRange range type, see <a + * href="www.boost.org/doc/libs/release/libs/range/doc/html/">boost.Range</a> + * to see what qualifies as an \em Range. + * \param os destination stream + * \param[in] range Range to print + * \param[in] separator Separator string to use between elements. + * + * \return the stream + * \throw None At least, this function is exception neutral. + */ +template <typename TRange> inline +std::ostream & Join(std::ostream &os, TRange const& range, std::string const& separator) +{ + if (!boost::empty(range)) + { + typename boost::range_iterator<TRange const>::type first = boost::begin(range); + typename boost::range_iterator<TRange const>::type const last = boost::end(range); + os << *first; + for (++first; first!=last; ++first) + { + os << separator << *first; + } + } + return os; +} +} // end namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +// #include "otbJoinContainer.txx" +#endif + +#endif // __otbJoinContainer_h diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.cxx index 5216555995d54b16110b1fb3ea65e5a0c06b5e96..58e732092b3342a67d43ceab03523b77671bbdeb 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.cxx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.cxx @@ -62,26 +62,16 @@ otb::ogr::Feature otb::ogr::Feature::clone() const void otb::ogr::Feature::PrintSelf(std::ostream & os, itk::Indent indent) const { CheckInvariants(); - const itk::Indent one_indent = itk::Indent().GetNextIndent(); - const int nbFields = m_Feature->GetFieldCount(); + const size_t nbFields = m_Feature->GetFieldCount(); os << indent << "+"; os << " " << nbFields << " fields\n"; - for (int i=0; i!=nbFields; ++i) { + indent = indent.GetNextIndent(); + for (size_t i=0; i!=nbFields; ++i) + { assert(ogr().GetFieldDefnRef(i)); - Field field(*this, i); - os << indent << "|" << one_indent << "+ "; - os << field.GetName() << ": "; - switch (field.GetType()) - { - case OFTInteger: os << field.GetValue<int>(); break; - case OFTReal : os << field.GetValue<double>(); break; - case OFTString : os << field.GetValue<std::string>(); - break; - default: os << "??? -> " << field.GetType(); break; - } - os << " (" << OGRFieldDefn::GetFieldTypeName(field.GetType()) << ")"; - os << "\n"; - } + Field const& field = (*this)[i]; + field.PrintSelf(os, indent); + } } bool otb::ogr::operator==(otb::ogr::Feature const& lhs, otb::ogr::Feature const& rhs) @@ -98,6 +88,20 @@ bool otb::ogr::operator==(otb::ogr::Feature const& lhs, otb::ogr::Feature const& ; } +/*===========================================================================*/ +/*================================[ Fields ]=================================*/ +/*===========================================================================*/ size_t otb::ogr::Feature::GetSize() const { return ogr().GetFieldCount(); } + +otb::ogr::Field otb::ogr::Feature::operator[](size_t index) +{ + Field field(*this, index); + return field; +} + +otb::ogr::Field const otb::ogr::Feature::operator[](size_t index) const +{ + return const_cast<Feature*>(this)->operator[](index); +} diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.h index c959ee65b61702a37041ad5b43c6c7d3fa077d20..c07675c412d1f0d1e7298c63cc3bbb350ca30a72 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.h @@ -22,6 +22,7 @@ #include <cassert> #include <boost/shared_ptr.hpp> #include "itkIndent.h" +#include "otbOGRFieldWrapper.h" class OGRFeature; class OGRGeometry; @@ -47,27 +48,22 @@ public: Feature clone() const; void PrintSelf(std::ostream &os, itk::Indent indent) const; - OGRFeature & ogr() const - { // not returning a OGRFeature const& because OGR is not const-correct - CheckInvariants(); - return *m_Feature; - } - OGRFeature & ogr() - { - CheckInvariants(); - return *m_Feature; - } + OGRFeature & ogr() const; + OGRFeature & ogr(); + boost::shared_ptr<OGRFeature> & sptr() {return m_Feature; } + boost::shared_ptr<OGRFeature> const& sptr() const {return m_Feature; } + /**\name Fields */ + //@{ size_t GetSize() const; + Field operator[](size_t index); + Field const operator[](size_t index) const; + //@} friend bool otb::ogr::operator==(Feature const& lhs, Feature const& rhs); private: - void CheckInvariants() const - { - assert(m_Feature && "OGRFeature can't be null"); - } + void CheckInvariants() const; boost::shared_ptr<OGRFeature> m_Feature; - }; @@ -76,7 +72,7 @@ private: #ifndef OTB_MANUAL_INSTANTIATION -// #include "otbOGRFeatureWrapper.txx" +#include "otbOGRFeatureWrapper.txx" #endif #endif // __otbOGRFeatureWrapper_h diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.txx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.txx new file mode 100644 index 0000000000000000000000000000000000000000..a55995e8a30827dbefe2a8b22aaed3bdfd3ee9d2 --- /dev/null +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.txx @@ -0,0 +1,48 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef __otbOGRFeatureWrapper_txx +#define __otbOGRFeatureWrapper_txx + +/*===========================================================================*/ +/*===============================[ Includes ]================================*/ +/*===========================================================================*/ + +/*===========================================================================*/ +/*================================[ Feature ]================================*/ +/*===========================================================================*/ +inline +OGRFeature & otb::ogr::Feature::ogr() const +{ // not returning a OGRFeature const& because OGR is not const-correct + CheckInvariants(); + return *m_Feature; +} + +inline +OGRFeature & otb::ogr::Feature::ogr() +{ + CheckInvariants(); + return *m_Feature; +} + +inline +void otb::ogr::Feature::CheckInvariants() const +{ + assert(m_Feature && "OGRFeature can't be null"); +} + +#endif // __otbOGRFeatureWrapper_txx diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d5e66405d6093494d16ce464c5c3553c6a1e723b --- /dev/null +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx @@ -0,0 +1,132 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +/*===========================================================================*/ +/*===============================[ Includes ]================================*/ +/*===========================================================================*/ +#include "otbOGRFieldWrapper.h" +#include <cassert> +#include "ogr_feature.h" +#include "otbOGRFeatureWrapper.h" +#include "otbJoinContainer.h" + +/*===========================================================================*/ +/*===========================[ Static Assertions ]===========================*/ +/*===========================================================================*/ +namespace types_ +{ +BOOST_STATIC_ASSERT(!(boost::is_same< + MemberGetterPtr<int, &OGRFeature::GetFieldAsInteger>, + MemberGetterPtr<double, &OGRFeature::GetFieldAsDouble> + >::value + )); + +BOOST_STATIC_ASSERT(!(boost::is_same< int, float >::value)); +BOOST_STATIC_ASSERT(!(boost::is_same< + int_<OFTReal >::type, + int_<OFTString>::type + >::value +)); +BOOST_STATIC_ASSERT(!(boost::is_same< + at<FieldType_Map, float>, + void_ + >::value +)); +BOOST_STATIC_ASSERT(!(boost::is_same< + at<FieldType_Map, double>, + int_<OFTReal> + >::value +)); +BOOST_STATIC_ASSERT(!(boost::is_same< + at<FieldType_Map, double >::type, + at<FieldType_Map, int >::type + >::value +)); +BOOST_STATIC_ASSERT(( + at<FieldType_Map, double>::type::value != + at<FieldType_Map, int >::type::value +)); +BOOST_STATIC_ASSERT(!(boost::is_same< + at<FieldGetters_Map, int_<OFTReal> >, + at<FieldGetters_Map, int_<OFTString> > + >::value +)); +} + +/*===========================================================================*/ +/*===============================[ FieldDefn ]===============================*/ +/*===========================================================================*/ + +std::string otb::ogr::FieldDefn::GetName() const +{ + assert(m_definition); + return m_definition->GetNameRef(); +} + +OGRFieldType otb::ogr::FieldDefn::GetType() const +{ + assert(m_definition); + return m_definition->GetType(); +} + +/*===========================================================================*/ +/*=================================[ Field ]=================================*/ +/*===========================================================================*/ + +otb::ogr::Field::Field(otb::ogr::Feature & feature, size_t index) +: m_Definition(*feature.ogr().GetFieldDefnRef(index)) +, m_Feature(feature.sptr()) +, m_index(index) +{ + assert(m_Feature); + assert(m_Feature->GetFieldDefnRef(index)); +} + +std::ostream & otb::ogr::Field::PrintSelf( + std::ostream& os, itk::Indent indent) const +{ + const itk::Indent one_indent = itk::Indent().GetNextIndent(); + // os << indent << "|" << one_indent << "+ "; + os << indent << this->GetName() << ": "; + switch (this->GetType()) + { + case OFTInteger: + os << this->GetValue<int>(); + break; + case OFTIntegerList: + os << '{'; + otb::Join(os, this->GetValue<std::vector<int> >(), ", ") << '}'; + break; + case OFTReal : + os << this->GetValue<double>(); + break; + case OFTRealList: + os << '{'; + otb::Join(os, this->GetValue<std::vector<double> >(), ", ") << '}'; + break; + case OFTString : + os << this->GetValue<std::string>(); + break; + default: + os << "??? -> " << this->GetType(); + break; + } + os << " (" << OGRFieldDefn::GetFieldTypeName(this->GetType()) << ")"; + os << "\n"; + return os; +} diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h index df05f05fdd88bcbf43478cd82446ed2c16506f1d..5d895b42c7114434491125e6576a1d2b56282fe3 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h @@ -26,14 +26,18 @@ #include <boost/mpl/int.hpp> #include <boost/mpl/at.hpp> -#include <boost/mpl/assert.hpp> +// #include <boost/mpl/assert.hpp> #include <boost/static_assert.hpp> #include <boost/type_traits/is_same.hpp> -// class OGRFeature; -#include "ogr_feature.h" +#include <boost/shared_ptr.hpp> class OGRFieldDefn; +// class OGRFeature; +#include "ogr_feature.h" // OGRFeature::*field_getters +#include "ogr_core.h" // OGR enums +#include "itkIndent.h" +#include <cassert> - +#if 0 #include <iomanip> template <typename RT, typename CT> void print_adress(RT (CT::*p)(int)) { @@ -47,9 +51,10 @@ template <typename RT, typename CT> void print_adress(RT (CT::*p)(int)) } std::cout << "\n"; } +#endif -namespace types_ { // Anonymous namespace +namespace types_ { // namespace types_ using namespace boost::mpl; typedef boost::mpl::map < pair<int, int_<OFTInteger> > @@ -58,87 +63,65 @@ typedef boost::mpl::map , pair<std::vector<double>, int_<OFTRealList> > , pair<std::string, int_<OFTString> > , pair<std::vector<std::string>, int_<OFTStringList> > + // OFTBinary + // OFTDate + // OFTTime + // OFTDateTime > FieldType_Map; template < typename T , T ( OGRFeature::*ptr_to_function )(int) , typename FinalReturnType = T - > class member_function_get_ptr + > class MemberGetterPtr { public: static FinalReturnType call(OGRFeature &f, int index) { - // print_adress(ptr_to_function); - // print_adress(&OGRFeature::GetFieldAsString); return (f.*ptr_to_function)(index); } }; +template + < typename T + , T const* ( OGRFeature::*ptr_to_function )(int, int*) + , typename FinalReturnType = std::vector<T> + > class MemberContainerGetterPtr + { + public: + static FinalReturnType call(OGRFeature &f, int index) + { + int nb = 0; + T const* raw_container = (f.*ptr_to_function)(index, &nb); + FinalReturnType res(raw_container+0, raw_container+nb); + return res; + } + }; + typedef map - < pair<int_<OFTInteger>, member_function_get_ptr<int, &OGRFeature::GetFieldAsInteger> > - , pair<int_<OFTReal>, member_function_get_ptr<double, &OGRFeature::GetFieldAsDouble> > - , pair<int_<OFTString>, member_function_get_ptr<char const*, &OGRFeature::GetFieldAsString, std::string> > + < pair<int_<OFTInteger>, MemberGetterPtr<int, &OGRFeature::GetFieldAsInteger> > + , pair<int_<OFTIntegerList>, MemberContainerGetterPtr<int, &OGRFeature::GetFieldAsIntegerList> > + , pair<int_<OFTReal>, MemberGetterPtr<double, &OGRFeature::GetFieldAsDouble> > + , pair<int_<OFTRealList>, MemberContainerGetterPtr<double, &OGRFeature::GetFieldAsDoubleList> > + , pair<int_<OFTString>, MemberGetterPtr<char const*, &OGRFeature::GetFieldAsString, std::string> > + // , pair<int_<OFTStringList>, MemberGetterPtr<char const*, &OGRFeature::GetFieldAsString, std::string> > > FieldGetters_Map; -BOOST_STATIC_ASSERT(!(boost::is_same< - member_function_get_ptr<int, &OGRFeature::GetFieldAsInteger>, - member_function_get_ptr<double, &OGRFeature::GetFieldAsDouble> - >::value - )); - -BOOST_STATIC_ASSERT(!(boost::is_same< int, float >::value)); -BOOST_STATIC_ASSERT(!(boost::is_same< - int_<OFTReal >::type, - int_<OFTString>::type - >::value - )); -BOOST_STATIC_ASSERT(!(boost::is_same< - at<FieldType_Map, float>, - void_ - >::value - )); -BOOST_STATIC_ASSERT(!(boost::is_same< - at<FieldType_Map, double>, - int_<OFTReal> - >::value - )); -BOOST_STATIC_ASSERT(!(boost::is_same< - at<FieldType_Map, double >::type, - at<FieldType_Map, int >::type - >::value - )); -BOOST_STATIC_ASSERT(( - at<FieldType_Map, double>::type::value != - at<FieldType_Map, int >::type::value - )); -BOOST_STATIC_ASSERT(!(boost::is_same< - at<FieldGetters_Map, int_<OFTReal> >, - at<FieldGetters_Map, int_<OFTString> > - >::value - )); -} // Anonymous namespace +} // namespace types_ namespace otb { namespace ogr { class FieldDefn { public: FieldDefn(OGRFieldDefn& definition) : m_definition(&definition){ } - std::string GetName() const - { - assert(m_definition); - return m_definition->GetNameRef(); - } - OGRFieldType GetType() const - { - assert(m_definition); - return m_definition->GetType(); - } + std::string GetName() const; + OGRFieldType GetType() const; private: OGRFieldDefn * m_definition; }; +#if 0 template <typename FieldType> struct FieldDecodingTraitsGetter {}; template <typename FieldType> struct FieldDecodingTraits { @@ -153,7 +136,7 @@ template <typename FieldType> struct FieldDecodingTraits template <> struct FieldDecodingTraitsGetter<int> { typedef int Type; - static Type Get(OGRFeature &f, int index) + static Type Get(OGRFeature &f, size_t index) { return f.GetFieldAsInteger(index); } @@ -162,7 +145,7 @@ template <> struct FieldDecodingTraitsGetter<int> template <> struct FieldDecodingTraitsGetter<double> { typedef double Type; - static Type Get(OGRFeature &f, int index) + static Type Get(OGRFeature &f, size_t index) { return f.GetFieldAsDouble(index); } @@ -171,25 +154,21 @@ template <> struct FieldDecodingTraitsGetter<double> template <> struct FieldDecodingTraitsGetter<std::string> { typedef std::string Type; - static Type Get(OGRFeature &f, int index) + static Type Get(OGRFeature &f, size_t index) { return f.GetFieldAsString(index); } }; +#endif /*===========================================================================*/ /*=================================[ Field ]=================================*/ /*===========================================================================*/ +class Feature; class Field { public: - Field(Feature const& feature, int index) - : m_Definition(*feature.ogr().GetFieldDefnRef(index)) - , m_Feature(feature) - , m_index(index) - { - assert(feature.ogr().GetFieldDefnRef(index)); - } + Field(Feature & feature, size_t index); // Field(OGRFeature& field, FieldDefn const& definition); FieldDefn const& GetDefinition() const; OGRFieldType GetType() const @@ -208,32 +187,19 @@ public: { const int VALUE = boost::mpl::at<types_::FieldType_Map, T>::type::value; typedef typename boost::mpl::at<types_::FieldType_Map, T>::type Kind; - BOOST_STATIC_ASSERT(!(boost::is_same< Kind, boost::mpl::void_ >::value)); + BOOST_STATIC_ASSERT(!(boost::is_same<Kind, boost::mpl::void_>::value)); assert(m_Definition.GetType() == Kind::value); - typedef typename boost::mpl::at< types_::FieldGetters_Map, Kind >::type function_; - BOOST_STATIC_ASSERT(!(boost::is_same< function_, boost::mpl::void_ >::value)); - assert(m_index >= 0 && m_index < m_Feature.GetSize()); - return function_::call(m_Feature.ogr(), m_index); - // return FieldDecodingTraitsGetter<T>::Get(m_Feature.ogr(), m_index); + typedef typename boost::mpl::at<types_::FieldGetters_Map, Kind>::type GetterType; + BOOST_STATIC_ASSERT(!(boost::is_same<GetterType, boost::mpl::void_>::value)); + assert(m_index >= 0 && m_index < m_Feature->GetFieldCount()); + return GetterType::call(*m_Feature, m_index); } -#if 0 - std::ostream & PrintSelf(std::ostream&os, itk::Indent indent) { - os << indent; - switch (GetType) - { -machin_int: - os << GetValue<int>(); - break; - default: - } - return os; - } -#endif + std::ostream & PrintSelf(std::ostream&os, itk::Indent indent) const; private: - FieldDefn m_Definition; - Feature m_Feature; - int m_index; // all the fields decoding is at the wrong place (OGRFeature instead of OGRField) + FieldDefn m_Definition; + boost::shared_ptr<OGRFeature> & m_Feature; + size_t m_index; // all the fields decoding is at the wrong place (OGRFeature instead of OGRField) }; } } // end namespace otb::ogr