/* * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES) * * This file is part of Orfeo Toolbox * * https://www.orfeo-toolbox.org/ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef mvdAlgorithm_h #define mvdAlgorithm_h // // Configuration include. //// Included at first position before any other ones. #include "ConfigureMonteverdi.h" #include "OTBMonteverdiCoreExport.h" /*****************************************************************************/ /* INCLUDE SECTION */ // // Qt includes (sorted by alphabetic order) //// Must be included before system/custom includes. #include // // System includes (sorted by alphabetic order) #include // // ITK includes (sorted by alphabetic order) #include "itkFixedArray.h" #include "itkExceptionObject.h" #include "itkVariableLengthVector.h" // // OTB includes (sorted by alphabetic order) // // Monteverdi includes (sorted by alphabetic order) #include "mvdTypes.h" /*****************************************************************************/ /* PRE-DECLARATION SECTION */ // // External classes pre-declaration. namespace { } namespace mvd { // // Internal classes pre-declaration. } // end of namespace 'mvd'. /*****************************************************************************/ /* FUNCTIONS DECLARATION. */ namespace otb { /** * Convert an itk::VariableLengthVector< T2 > into a * itk::FixedArray< T1, N >. * * Elements of type T1 are (safely) statically casted into T2. * * An itk::RangeError exception instance is thrown if lengths/sizes of * both the containers are not equal. * * N.B.: Caller must ensure to that size N of itk::FixedArray< T1, N > * to match the variable size of the itk::VariableLengthVector< T1 >. */ template inline itk::FixedArray ToFixedArray(const itk::VariableLengthVector& v); /** * Convert an itk::VariableLengthVector< T2 > into a * itk::FixedArray< T1, N >. * * Elements of type T1 are (safely) statically casted into T2. * * An itk::RangeError exception instance is thrown if lengths/sizes of * both the containers are not equal. * * N.B.: Caller must ensure to that size N of itk::FixedArray< T1, N > * to match the variable size of the itk::VariableLengthVector< T1 >. */ template inline itk::FixedArray& ToFixedArray(itk::FixedArray& a, const itk::VariableLengthVector& v); /** * Convert an itk::FixedArray< T2, N > into a * itk::VariableLengthVector< T1 >. * * Elements of type T1 are (safely) statically casted into T2. * * An itk::RangeError exception instance is thrown if lengths/sizes of * both the containers are not equal. */ template inline itk::VariableLengthVector ToVariableLengthVector(const itk::FixedArray& a); /** * Convert an itk::FixedArray< T2, N > into a * itk::VariableLengthVector< T1 >. * * Elements of type T1 are (safely) statically casted into T2. * * An itk::RangeError exception instance is thrown if lengths/sizes of * both the containers are not equal. */ template inline itk::VariableLengthVector& ToVariableLengthVector(itk::FixedArray& a, const itk::VariableLengthVector& v); } // end namespace 'otb' /*****************************************************************************/ namespace mvd { /** * \brief Write an itk::VariableLengthVector< T > into a QTextStream. * * \param stream QTextStream into which to write data. * \param vector itk::VariableLengthVector< T > data to write. * * \return stream instance. */ template inline QTextStream& operator<<(QTextStream& stream, const itk::VariableLengthVector& vector); /** * \brief Write an itk::VariableLengthVector< T > into a QTextStream. * * \param stream QTextStream into which to write data. * \param vector itk::VariableLengthVector< T > data to write. * * \return stream instance. */ template inline QTextStream& operator>>(QTextStream& stream, itk::VariableLengthVector& vector); /** * \brief Write an itk::VariableLengthVector< T > into a QDataStream. * * \param stream QDataStream into which to write data. * \param vector itk::VariableLengthVector< T > data to write. * * \return stream instance. */ template inline QDataStream& operator<<(QDataStream& stream, const itk::VariableLengthVector& vector); /** * \brief Write an itk::VariableLengthVector< T > into a QDataStream. * * \param stream QDataStream into which to write data. * \param vector itk::VariableLengthVector< T > data to write. * * \return stream instance. */ template inline QDataStream& operator>>(QDataStream& stream, itk::VariableLengthVector& vector); /** * \brief Convert a StringVector object to a QStringList object. * * Because Qt uses a shallow mechanism to copy containers, the returned * QStringList is shallow-copied. */ inline QStringList ToQStringList(const StringVector& sv); /** * \brief Append the content of a StringVector object to the content * of a QStringList object. * * Because Qt uses a shallow mechanism to copy containers, the returned * QStringList is shallow-copied. */ inline QStringList& AppendToQStringList(QStringList& qsl, const StringVector& sv); /** * \brief Convert and copy an STL std::string to a QString. * * The 8-bit data is converted to Unicode using the * QString::fromAscii() method. * * \param str The 8-bit STL string to convert. * * \return The Unicode converted QString. */ inline QString FromStdString(const std::string& str); /** */ inline std::string ToLocalStdString(const QString&); /** */ inline const char* ToLocalString(const QString&); /** * \brief Convert and copy a QString to a STL std::string. * * The Unicode data is converted to 8-bit using the QString::toLatin1() * method. * * \param str The Unicode string to convert. * * \return The 8-bit converted STL std::string. */ inline std::string ToStdString(const QString& str); /** */ inline const char* ToString(const QString& str); /** * \return a std::string form various types. */ inline std::string ToStdString(unsigned int val); inline std::string ToStdString(const SpacingType& spacing); inline std::string ToStdString(const SizeType& size); inline std::string ToStdString(const PointType& point); template std::string ToStdString(const std::vector& vec); /** */ template inline QString ToQString(const T& val); /** */ template <> inline QString ToQString(const float&); /** */ template <> inline QString ToQString(const double&); /** */ inline QString ToHumanReadableSize(qint64 fize, bool isInBits = true); } // end namespace 'mvd'. /*****************************************************************************/ namespace mvd { /** * \brief Test condition on all elements in range. * * \param first First element of range to test. * \param last Upper (external) boundary of range to test. * \param pred Predicate testing element in range. * * \return true if predicate is true on all elements in the range * [first, last[ or if range is empty. */ template inline bool AllOf(TInputIterator first, TInputIterator last, TUnaryPredicate pred); /** * \brief Test if any of element in range fulfills condition. * * \param first First element of range to test. * \param last Upper (external) boundary of range to test. * \param pred Predicate testing element in range. * * \return true if predicated is true for, at least, one element in range * [first, last[. If range is empty, this function returns false. */ template inline bool AnyOf(TInputIterator first, TInputIterator last, TUnaryPredicate pred); /** * \brief Test if no element in range fulfills condition. * * \param first First element of range to test. * \param last Upper (external) boundary of range to test. * \param pred Predicate testing element in range. * * \return true if predicated is false for all elements in range [first, last[. If range is empty, this function returns true. */ template inline bool NoneOf(TInputIterator first, TInputIterator last, TUnaryPredicate pred); } // end namespace 'mvd'. /*****************************************************************************/ /* INLINE SECTION */ namespace otb { /*******************************************************************************/ template inline itk::FixedArray ToFixedArray(const itk::VariableLengthVector& v) { assert(v.Size() == N); throw itk::RangeError(__FILE__, __LINE__); itk::FixedArray a; for (unsigned int i = 0; i < N; ++i) a[i] = static_cast(v[i]); return a; } /*******************************************************************************/ template inline itk::FixedArray& ToFixedArray(itk::FixedArray& a, const itk::VariableLengthVector& v) { assert(v.Size() == N && v.Size() == a.Size()); throw itk::RangeError(__FILE__, __LINE__); for (unsigned int i = 0; i < N; ++i) a[i] = static_cast(v[i]); return a; } /*******************************************************************************/ template inline itk::VariableLengthVector ToVariableLengthVector(const itk::FixedArray& a) { assert(a.Size() == N); throw itk::RangeError(__FILE__, __LINE__); itk::VariableLengthVector v; v.Reserve(N); for (unsigned int i = 0; i < N; ++i) v[i] = static_cast(a[i]); return v; } /*******************************************************************************/ template inline itk::VariableLengthVector& ToVariableLengthVector(itk::VariableLengthVector& v, const itk::FixedArray& a) { assert(a.Size() == N); throw itk::RangeError(__FILE__, __LINE__); v.Reserve(N); for (unsigned int i = 0; i < N; ++i) v[i] = static_cast(a[i]); return v; } } // end namespace 'otb'. namespace mvd { /*******************************************************************************/ inline QStringList ToQStringList(const StringVector& sv) { QStringList qsl; return AppendToQStringList(qsl, sv); } /*******************************************************************************/ inline QStringList& AppendToQStringList(QStringList& qsl, const StringVector& sv) { for (StringVector::const_iterator it(sv.begin()); it != sv.end(); ++it) { qsl.append(QString(it->c_str())); } return qsl; } /*******************************************************************************/ inline std::string ToLocalStdString(const QString& str) { return std::string(str.toLocal8Bit().constData()); } /*******************************************************************************/ inline const char* ToLocalString(const QString& str) { return str.toLocal8Bit().constData(); } /*******************************************************************************/ inline QString FromStdString(const std::string& str) { return QString(str.c_str()); } /*******************************************************************************/ inline std::string ToStdString(const QString& str) { return std::string(str.toLatin1().constData()); } /*******************************************************************************/ inline const char* ToString(const QString& str) { return str.toLatin1().constData(); } /*******************************************************************************/ inline std::string ToStdString(unsigned int val) { std::ostringstream oss; oss << val; return oss.str(); } /*******************************************************************************/ inline std::string ToStdString(const SpacingType& spacing) { std::ostringstream oss; oss << spacing[0] << " , " << spacing[1]; return oss.str(); } /*******************************************************************************/ inline std::string ToStdString(const SizeType& size) { std::ostringstream oss; oss << size[0] << " , " << size[1]; return oss.str(); } /*******************************************************************************/ inline std::string ToStdString(const PointType& point) { std::ostringstream oss; oss << point[0] << " , " << point[1]; return oss.str(); } /*******************************************************************************/ template inline std::string ToStdString(const std::vector& vec) { std::ostringstream oss; typename std::vector::const_iterator it = vec.begin(); while (it != vec.end()) { oss << *it << " "; ++it; } return oss.str(); } /*******************************************************************************/ template inline QString ToQString(const T& val) { return QString("%1").arg(val); } /*****************************************************************************/ template <> inline QString ToQString(const float& val) { assert(!std::isnan(val)); QString valf; // See IEEE-754 // Ref. http://en.wikipedia.org/wiki/Single-precision_floating-point_format valf.sprintf("%.9g", val); #if 0 std::cout << "ToString< float >(" << val << "): " << ToStdString( valf ) << "\t" << valf.toFloat() << std::endl; #endif if (valf.toFloat() != val) throw std::runtime_error( ToStdString(QCoreApplication::translate("mvd::DatasetDescritor", "Accuracy loss when converting float (%1) to string.").arg(valf))); return valf; } /*****************************************************************************/ template <> inline QString ToQString(const double& val) { assert(!std::isnan(val)); QString vald; // See IEEE-754 // Ref. http://en.wikipedia.org/wiki/Double_precision vald.sprintf("%.17g", val); #if 0 std::cout << "ToString< double >(" << val << "): " << ToStdString( vald ) << "\t" << vald.toDouble() << std::endl; #endif if (vald.toDouble() != val) throw std::runtime_error( ToStdString(QCoreApplication::translate("mvd::DatasetDescriptor", "Accuracy loss when converting double (%1) to string.").arg(vald))); return vald; } } // end namespace 'mvd' namespace mvd { /*******************************************************************************/ template inline bool AllOf(TInputIterator first, TInputIterator last, TUnaryPredicate pred) { while (first != last) { if (!pred(*first)) return false; ++first; } return true; } /*******************************************************************************/ template inline bool AnyOf(TInputIterator first, TInputIterator last, TUnaryPredicate pred) { while (first != last) { if (pred(*first)) return true; ++first; } return false; } /*******************************************************************************/ template inline bool NoneOf(TInputIterator first, TInputIterator last, TUnaryPredicate pred) { while (first != last) { if (pred(*first)) return false; ++first; } return true; } /*******************************************************************************/ inline QString ToHumanReadableSize(qint64 size, bool isInBits) { double thousand = isInBits ? 1024.0 : 1000.0; double remainder = static_cast(size); if (size < thousand) return QString::number(size); remainder /= thousand; if (remainder < thousand) return QString("%1 KiB").arg(QString::number(remainder, 'g', 3)); remainder /= thousand; if (remainder < thousand) return QString("%1 MiB").arg(QString::number(remainder, 'g', 3)); remainder /= thousand; if (remainder < thousand) return QString("%1 GiB").arg(QString::number(remainder, 'g', 3)); remainder /= thousand; return QString("%1 TiB").arg(QString::number(remainder, 'g', 3)); } } // end namespace 'mvd' #endif // mvdAlgorithm_h