/* * 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 otbOGRFieldWrapper_h #define otbOGRFieldWrapper_h #include #include class OGRFieldDefn; class OGRFeature; #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable : 4251) #include "ogr_core.h" // OGR enums #pragma warning(pop) #else #include "ogr_core.h" // OGR enums #endif #include "itkIndent.h" #include "OTBGdalAdaptersExport.h" namespace otb { namespace ogr { /*===========================================================================*/ /*===========================[ Field definition ]============================*/ /*===========================================================================*/ /**\ingroup gGeometry * \class FieldDefn * \brief Encapsulation of \c OGRFieldDefn: field definition. * \invariant m_Definition != 0 * \invariant \c m_Definition lifetime is of the responsibility of the owning \c * \c OGRFeatureDefn. * \sa OGRFieldDefn * \since OTB v 3.14.0 * * \ingroup OTBGdalAdapters */ class OTBGdalAdapters_EXPORT FieldDefn { public: FieldDefn(OGRFieldDefn& definition) : m_Definition(&definition) { } std::string GetName() const; //!< Field name accessor. OGRFieldType GetType() const; //!< Field type accessor. OGRFieldDefn& ogr() { return *m_Definition; } OGRFieldDefn& ogr() const { return *m_Definition; } private: /**Pointer to the actual definition. * \internal pointer in order to support assignments */ OGRFieldDefn* m_Definition; }; inline bool operator==(FieldDefn const& lhs, FieldDefn const& rhs) { return lhs.GetName() == rhs.GetName() && lhs.GetType() == rhs.GetType(); } OTBGdalAdapters_EXPORT std::ostream& operator<<(std::ostream& os, FieldDefn const& defn); /*===========================================================================*/ /*=================================[ Field ]=================================*/ /*===========================================================================*/ class Feature; /**\ingroup gGeometry * \class Field * \brief Encapsulation of \c OGRField * Instances of \c Field are expected to be built from an existing \c Feature * with which they'll share their owning \c OGRFeature. * * A \c Field instance works as a proxy. Copying a field will only have it share * the actual \c OGRField between several instances. In order to copy a field * value from another field, use \c Field::assign(). * * \invariant m_Feature shall be valid (i.e. not wrapping a null \c * OGRFeature). * \invariant m_index < m_Feature->GetFieldCount(). * \invariant m_Feature->GetFieldDefnRef(m_index) != 0. * \sa OGRField * \since OTB v 3.14.0 * * \ingroup OTBGdalAdapters */ class OTBGdalAdapters_EXPORT Field { public: /** * Constructor. * \param[in,out] feature \c Feature from which the field is. * \param[in] index Index of the field in the \c Feature. * \throw None */ Field(Feature& feature, int index); /// %Field definition accessor. FieldDefn const& GetDefinition() const { return m_Definition; } /// %Field type accessor. OGRFieldType GetType() const { return m_Definition.GetType(); } /// %Field name accessor. std::string GetName() const { return m_Definition.GetName(); } /// Tells whether the field value has been set. bool HasBeenSet() const; /// Unsets the value of the field. void Unset() const; /** * Value setter. * \param[in] value New value for the field. * \throw None * \pre \c value's kind must match the field's type. * \internal * This function automagically decodes the type of the parameter in order to * use the ad'hoc setter from \c OGRFeature. */ template void SetValue(T const& value); /** * Value getter. * \tparam T expected type for the stored value. * \throw None * \pre \c T must match the field's type. * \pre The field must have set. * \internal * This function automagically deduce the ad'hoc getter (from \c OGRFeature) * from \c T. */ template T GetValue() const; /** Prints self into stream. */ std::ostream& PrintSelf(std::ostream& os, itk::Indent indent) const; /** Copies a field. * As \c Field is a proxy type, this function is the only possible way to copy a field. * * First, the field must be defined with a definition, then it could be set * from another field value. * \code * Field srcField = srcFeature[42]; * Feature dstFeature(layerDefinition); * Field dst(dstFeature, 12); * dstField.Assign(srcField); * \endcode */ void Assign(Field const& f); /** \copydoc Field::ogr() const */ OGRField& ogr(); /** Access to the raw underlying OGR data. * This function provides an abstraction leak in case deeper control on the * underlying \c OGRFeature is required. * \warning You must under no circumstance try to delete the \c OGRField * obtained this way. */ OGRField& ogr() const; private: /**\name Unchecked definitions * All the definitions that follow do the real work. However, they are not the * exposed public functions. The design of this class follows the principle * behind the NVI (Non-Virtual Interface) pattern: * - The public functions are inlined and check invariants and preconditions, * - While the private functions do the work. */ //@{ bool UncheckedHasBeenSet() const; void UncheckedUnset() const; std::ostream& UncheckedPrintSelf(std::ostream& os, itk::Indent indent) const; void UncheckedAssign(Field const& f); //@} /** * Internal function to check class invariants. * If any invariant is broken, an assertion will be fired. * \internal * This function is defined inlined in order to be able to inhibit invariants * checking depending on the compilation mode (on \c NDEBUG preprocessor * define actually). */ void CheckInvariants() const; /// Definition of the field. FieldDefn m_Definition; /// Link to the actual \c OGRFeature in charge of the fields. boost::shared_ptr& m_Feature; /** Index of the field according to the feature definition. * \internal * All the fields decoding is at the wrong place (\c OGRFeature instead of * \c OGRField) => need for an index. */ int m_index; }; } } // end namespace otb::ogr #ifndef OTB_MANUAL_INSTANTIATION #include "otbOGRFieldWrapper.hxx" #endif #endif // otbOGRFieldWrapper_h