diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx index eee8ee907d352ca04453c075dae44183ceb8e1e5..15def7ef1b5ffe89ba55ca7e8af40c64c6afbcb3 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx @@ -159,3 +159,16 @@ void otb::ogr::Field::UncheckedUnset() const { m_Feature->UnsetField(m_index); } + +void otb::ogr::Field::UncheckedAssign(Field const& f) +{ + if (f.HasBeenSet()) + { + OGRField & of = f.ogr(); + m_Feature->SetField(m_index, &of); // OGR API copies *of + } + else // not sure OGR setField handle the case where new fields are unset + { + this->Unset(); + } +} diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h index c80bce4d7a8929f9fe873c37a353587d046c8f95..8bcea0628765db9861cf7fd9c49772780243729a 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h @@ -77,6 +77,10 @@ class Feature; * 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 <tt>m_Feature</tt> shall be valid (i.e. not wrapping a null \c * OGRFeature). * \invariant <tt>m_index < m_Feature->GetFieldCount()</tt>. @@ -133,6 +137,31 @@ public: /** 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); + + /** 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 circonstance try to delete the \c OGRField + * obtained this way. + */ + OGRField & ogr() const; + + /** \copydoc Field::ogr() const */ + OGRField & ogr(); private: /**\name Unchecked definitions * All the definitions that follow do the real work. However, they are not the @@ -145,6 +174,7 @@ private: bool UncheckedHasBeenSet() const; void UncheckedUnset() const; std::ostream & UncheckedPrintSelf(std::ostream&os, itk::Indent indent) const; + void UncheckedAssign(Field const& f); //@} /** diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.txx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.txx index 75c73fbb9466112a5237d9f24655b97c12d37c2b..d519b21a90c3d68194d7abcef3315b9e9ee1e533 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.txx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.txx @@ -439,4 +439,29 @@ void otb::ogr::Field::Unset() const UncheckedUnset(); } +inline +void otb::ogr::Field::Assign(Field const& f) +{ + CheckInvariants(); + f.CheckInvariants(); + assert(f.GetDefinition() == this->GetDefinition() && "Cannot assign from a field that doesn't have the same definition"); + UncheckedAssign(f); + CheckInvariants(); +} + +inline +OGRField & otb::ogr::Field::ogr() const +{ + return const_cast <Field*>(this)->ogr(); +} + +inline +OGRField & otb::ogr::Field::ogr() +{ + CheckInvariants(); + OGRField * f = m_Feature->GetRawFieldRef(m_index); + assert(f && "The field obtained shall not be null"); + return *f; +} + #endif // __otbOGRFieldWrapper_txx