From 812e9d94602e5a6b8fcc124c99457c9f1b8715cc Mon Sep 17 00:00:00 2001 From: Luc Hermitte <luc.hermitte@c-s.fr> Date: Thu, 31 May 2012 18:51:35 +0200 Subject: [PATCH] ENH: OTB-134/OGR -> + Field copy --- .../OGRAdapters/otbOGRFieldWrapper.cxx | 13 ++++++++ .../OGRAdapters/otbOGRFieldWrapper.h | 30 +++++++++++++++++++ .../OGRAdapters/otbOGRFieldWrapper.txx | 25 ++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx index eee8ee907d..15def7ef1b 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 c80bce4d7a..8bcea06287 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 75c73fbb94..d519b21a90 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 -- GitLab