diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx index af319236f5f199b3018525dc440cdc6bef817d01..d714051526b91ca056376a667b0b4f8dfb1db80c 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.cxx @@ -93,6 +93,12 @@ OGRFieldType otb::ogr::FieldDefn::GetType() const return m_Definition->GetType(); } + +std::ostream & otb::ogr::operator<<(std::ostream & os, otb::ogr::FieldDefn const& defn) +{ + return os << defn.GetName() + << " (" << OGRFieldDefn::GetFieldTypeName(defn.GetType()) << ")"; +} /*===========================================================================*/ /*=================================[ Field ]=================================*/ /*===========================================================================*/ diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h index 4fa1d6b38e389dca26dcdb7767a7091d94ca1355..c80bce4d7a8929f9fe873c37a353587d046c8f95 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h @@ -47,6 +47,9 @@ public: 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 @@ -54,6 +57,14 @@ private: OGRFieldDefn * m_Definition; }; +inline +bool operator==(FieldDefn const& lhs, FieldDefn const& rhs) + { + return lhs.GetName() == rhs.GetName() + && lhs.GetType() == rhs.GetType(); + } + +std::ostream & operator<<(std::ostream & os, FieldDefn const& defn); /*===========================================================================*/ /*=================================[ Field ]=================================*/ diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.txx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.txx index cda766e6fca56078f45eaf9983980fa996bc9b20..5b16a89cd934e6b806ba1ae035d8c8e1bea25d74 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.txx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.txx @@ -117,6 +117,7 @@ template template < typename T , void ( OGRFeature::*ptr_to_function )(int, T value) + , typename ActualParamType = T > class MemberSetterPtr { public: @@ -263,8 +264,8 @@ typedef map , pair<int_<OFTIntegerList>, MemberContainerSetterPtr<int, &OGRFeature::SetField> > , pair<int_<OFTReal>, MemberSetterPtr<double, &OGRFeature::SetField> > , pair<int_<OFTRealList>, MemberContainerSetterPtr<double, &OGRFeature::SetField> > - // , pair<int_<OFTString>, MemberSetterPtr<char const*, &OGRFeature::SetField, std::string> > - // , pair<int_<OFTStringList>, MemberSetterPtr<char const*, &OGRFeature::GetFieldAsString, std::string> > + // , pair<int_<OFTString>, MemberSetterPtr<char const*, &OGRFeature::SetField/*, std::string*/> > + // , pair<int_<OFTStringList>, MemberContainerSetterPtr<char const*, &OGRFeature::SetField, std::string> > > FieldSetters_Map; } // namespace internal diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx index 84f232a6c2bc02ac820455fcbab5e2f0f70ab1b3..b40527010103c526648adbabca2fa2e00c228e4c 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx @@ -219,10 +219,10 @@ OGRFeatureDefn & otb::ogr::Layer::GetLayerDefn() const } void otb::ogr::Layer::CreateField( - OGRFieldDefn const& field, bool bApproxOK/* = true */) + FieldDefn const& field, bool bApproxOK/* = true */) { assert(m_Layer && "OGRLayer not initialized"); - const OGRErr res = m_Layer->CreateField(const_cast <OGRFieldDefn*>(&field), bApproxOK); + const OGRErr res = m_Layer->CreateField(&field.ogr(), bApproxOK); if (res != OGRERR_NONE) { itkGenericExceptionMacro(<< "Cannot create a field in the layer <" @@ -247,7 +247,7 @@ void otb::ogr::Layer::DeleteField(size_t fieldIndex) } void otb::ogr::Layer::AlterFieldDefn( - size_t fieldIndex, OGRFieldDefn const& newFieldDefn, int nFlags) + size_t fieldIndex, FieldDefn const& newFieldDefn, int nFlags) { assert(m_Layer && "OGRLayer not initialized"); #if GDAL_VERSION_NUM < 1900 @@ -256,7 +256,7 @@ void otb::ogr::Layer::AlterFieldDefn( #else const OGRErr res = m_Layer->AlterFieldDefn( int(fieldIndex), - const_cast <OGRFieldDefn*>(&newFieldDefn), + &newFieldDefn.ogr(), nFlags); if (res != OGRERR_NONE) { diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h index 987fc2a9b541ccd43c11548828776e71da41fa6a..2245455018168e85db7c63376f46cfbe289568d9 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h @@ -31,7 +31,6 @@ class OGRLayer; class OGRDataSource; class OGRGeometry; class OGRFeatureDefn; -class OGRFieldDefn; namespace otb { namespace ogr { /**\ingroup gGeometry @@ -366,7 +365,7 @@ public: * \sa \c OGRLayer::CreateField() * \todo Move to use \c otb::ogr::FieldDefn */ - void CreateField(OGRFieldDefn const& field, bool bApproxOK = true); + void CreateField(FieldDefn const& field, bool bApproxOK = true); /** * Deletes a field. @@ -398,7 +397,7 @@ public: * v1.9.0 at least. * \todo Move to use \c otb::ogr::FieldDefn */ - void AlterFieldDefn(size_t fieldIndex, OGRFieldDefn const& newFieldDefn, int nFlags); + void AlterFieldDefn(size_t fieldIndex, FieldDefn const& newFieldDefn, int nFlags); /** * Moves a field from one position to another. diff --git a/Testing/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapperNew.cxx b/Testing/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapperNew.cxx index 21a27c1aa4cf1231543af6adfa8b2265348f3c41..1e584a0436668c0c0e2358635c325b3c8dceb97e 100644 --- a/Testing/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapperNew.cxx +++ b/Testing/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapperNew.cxx @@ -36,7 +36,27 @@ using namespace otb; */ /*===========================================================================*/ -/*==============================[ other stuff ]==============================*/ +/*===============================[ Constants ]===============================*/ +/*===========================================================================*/ +const std::string k_one = "one"; +const std::string k_two = "two"; + +/*const*/ OGRFieldDefn k_f0_("OFTInteger", OFTInteger); +/*const*/ OGRFieldDefn k_f1_("OFTReal", OFTReal); +/*const*/ OGRFieldDefn k_f2_("OFTString", OFTString); +/*const*/ OGRFieldDefn k_f3_("OFTIntegerList", OFTIntegerList); +/*const*/ OGRFieldDefn k_f4_("OFTRealList", OFTRealList); +/*const*/ OGRFieldDefn k_f5_("OFTStringList", OFTStringList); + +ogr::FieldDefn k_f0(k_f0_); +ogr::FieldDefn k_f1(k_f1_); +ogr::FieldDefn k_f2(k_f2_); +ogr::FieldDefn k_f3(k_f3_); +ogr::FieldDefn k_f4(k_f4_); +ogr::FieldDefn k_f5(k_f5_); + +/*===========================================================================*/ +/*==================================[ UTs ]==================================*/ /*===========================================================================*/ BOOST_AUTO_TEST_CASE(OGRDataSource_new_empty) @@ -46,13 +66,9 @@ BOOST_AUTO_TEST_CASE(OGRDataSource_new_empty) BOOST_CHECK_EQUAL(ds->GetLayersCount(), 0); BOOST_CHECK_EQUAL(ds->Size(false), 0); BOOST_CHECK_EQUAL(ds->Size(true), 0); - BOOST_CHECK_EQUAL(ds->GetLayerChecked(0),otb::ogr::Layer(0)); BOOST_CHECK_THROW(ds->GetLayerChecked(0), itk::ExceptionObject); } -const std::string k_one = "one"; -const std::string k_two = "two"; - BOOST_AUTO_TEST_CASE(OGRDataSource_mem_add_n_del_layer) { ogr::DataSource::Pointer ds = ogr::DataSource::New(); @@ -127,3 +143,105 @@ BOOST_AUTO_TEST_CASE(OGRDataSource_new_shp) // BOOST_CHECK_THROW(ds -> CreateLayer(k_two), itk::ExceptionObject); // BOOST_CHECK_EQUAL(ds->GetLayersCount(), 1); } + +BOOST_AUTO_TEST_CASE(Add_n_Del_Fields) +{ + ogr::DataSource::Pointer ds = ogr::DataSource::New(); + ogr::Layer l = ds -> CreateLayer(k_one); + ogr::Layer l0 = ds->GetLayerChecked(0); + + OGRFeatureDefn & defn = l.GetLayerDefn(); + BOOST_CHECK_EQUAL(defn.GetFieldCount(), 0); + l.CreateField(k_f0); + BOOST_CHECK_EQUAL(defn.GetFieldCount(), 1); + l.CreateField(k_f1); + BOOST_CHECK_EQUAL(defn.GetFieldCount(), 2); + l.CreateField(k_f2); + BOOST_CHECK_EQUAL(defn.GetFieldCount(), 3); + l.CreateField(k_f3); + BOOST_CHECK_EQUAL(defn.GetFieldCount(), 4); + l.CreateField(k_f4); + BOOST_CHECK_EQUAL(defn.GetFieldCount(), 5); + l.CreateField(k_f5); + BOOST_CHECK_EQUAL(defn.GetFieldCount(), 6); + + { + ogr::FieldDefn f0(*defn.GetFieldDefn(0)); + BOOST_CHECK_EQUAL(f0, k_f0); + ogr::FieldDefn f1(*defn.GetFieldDefn(1)); + BOOST_CHECK_EQUAL(f1, k_f1); + ogr::FieldDefn f2(*defn.GetFieldDefn(2)); + BOOST_CHECK_EQUAL(f2, k_f2); + ogr::FieldDefn f3(*defn.GetFieldDefn(3)); + BOOST_CHECK_EQUAL(f3, k_f3); + ogr::FieldDefn f4(*defn.GetFieldDefn(4)); + BOOST_CHECK_EQUAL(f4, k_f4); + ogr::FieldDefn f5(*defn.GetFieldDefn(5)); + BOOST_CHECK_EQUAL(f5, k_f5); + + BOOST_CHECK_EQUAL(defn.GetFieldDefn(6), (void*)0); + } + + l.DeleteField(1); + BOOST_CHECK_EQUAL(defn.GetFieldCount(), 5); + + { + ogr::FieldDefn f0(*defn.GetFieldDefn(0)); + BOOST_CHECK_EQUAL(f0, k_f0); + ogr::FieldDefn f1(*defn.GetFieldDefn(1)); + BOOST_CHECK_EQUAL(f1, k_f2); + ogr::FieldDefn f2(*defn.GetFieldDefn(2)); + BOOST_CHECK_EQUAL(f2, k_f3); + ogr::FieldDefn f3(*defn.GetFieldDefn(3)); + BOOST_CHECK_EQUAL(f3, k_f4); + ogr::FieldDefn f4(*defn.GetFieldDefn(4)); + BOOST_CHECK_EQUAL(f4, k_f5); + } + // todo: add reoder tests +} + +BOOST_AUTO_TEST_CASE(Add_n_Read_Fields) +{ + ogr::DataSource::Pointer ds = ogr::DataSource::New(); + ogr::Layer l = ds -> CreateLayer(k_one); + ogr::Layer l0 = ds->GetLayerChecked(0); + + OGRFeatureDefn & defn = l.GetLayerDefn(); + l.CreateField(k_f0); + l.CreateField(k_f1); + l.CreateField(k_f2); + l.CreateField(k_f3); + l.CreateField(k_f4); + l.CreateField(k_f5); + + ogr::Feature g0(defn); + const size_t NbFields = defn.GetFieldCount(); + BOOST_CHECK_EQUAL(NbFields, g0.GetSize()); + for (size_t i=0; i!=NbFields; ++i) + { + BOOST_ASSERT(!g0[i].HasBeenSet()); + } + + ogr::Field f0 = g0[0]; + BOOST_CHECK_EQUAL(f0.GetName(), k_f0.GetName()); + f0.SetValue(42); + BOOST_ASSERT(f0.HasBeenSet()); + BOOST_CHECK_EQUAL(f0.GetValue<int>(), 42); + // BOOST_CHECK_assert_FAILS(f0.GetValue<double>(), itk::ExceptionObject); + + ogr::Field f1 = g0["OFTReal"]; + BOOST_CHECK_EQUAL(f1.GetName(), k_f1.GetName()); + // f1.SetValue(42); // need to support types promotion + f1.SetValue(42.0); // need to support types promotion + BOOST_ASSERT(f1.HasBeenSet()); + BOOST_CHECK_EQUAL(f1.GetValue<double>(), 42.0); + +#if 0 // not ready + ogr::Field f2 = g0["OFTString"]; + BOOST_CHECK_EQUAL(f2.GetName(), k_f2.GetName()); + f2.SetValue(("foobar")); // need to support types promotion + BOOST_ASSERT(f2.HasBeenSet()); + BOOST_CHECK_EQUAL(f2.GetValue<std::string>(), "foobar"); +#endif + +}