diff --git a/Applications/Rasterization/otbRasterization.cxx b/Applications/Rasterization/otbRasterization.cxx index 754eb84448c7af9d9a5315b33946222ef2b50315..f41100699b2a1c74160db71dabc5df1436264850 100644 --- a/Applications/Rasterization/otbRasterization.cxx +++ b/Applications/Rasterization/otbRasterization.cxx @@ -151,7 +151,7 @@ private: otb::ogr::DataSource::Pointer ogrDS; UInt8ImageType::Pointer referenceImage; - ogrDS = otb::ogr::DataSource::New(GetParameterString("in"), otb::ogr::DataSource::Modes::read); + ogrDS = otb::ogr::DataSource::New(GetParameterString("in"), otb::ogr::DataSource::Modes::Read); bool validInputProjRef = false; std::string inputProjectionRef = ""; diff --git a/Applications/Segmentation/otbSegmentation.cxx b/Applications/Segmentation/otbSegmentation.cxx index c40d016049b3b2851c16d8151710f473a477b6f9..bfac43652f1e1ca9a1efa57ce6132283dd2e6dbf 100644 --- a/Applications/Segmentation/otbSegmentation.cxx +++ b/Applications/Segmentation/otbSegmentation.cxx @@ -451,7 +451,7 @@ private: if(GetParameterString("mode.vector.outmode") == "ovw") { // Create the datasource - ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::write); + ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Update_LayerOverwrite); // and create the layer since we are in overwrite mode, the // datasource is blank diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.cxx index ef7553b7d21f1aabba410cdf2142e92c5d655891..e20ea7053ed4d33258c60f6dd09b0be40dac17c3 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.cxx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.cxx @@ -114,7 +114,9 @@ char const* DeduceDriverName(std::string filename) otb::ogr::DataSource::DataSource() -: m_DataSource(0) +: m_DataSource(0), + m_OpenMode(Modes::Update_LayerOverwrite), + m_FirstModifiableLayerID(0) { Drivers::Init(); @@ -127,13 +129,49 @@ otb::ogr::DataSource::DataSource() m_DataSource->SetDriver(d); } -otb::ogr::DataSource::DataSource(OGRDataSource * source) -: m_DataSource(source) +otb::ogr::DataSource::DataSource(OGRDataSource * source, Modes::type mode) +: m_DataSource(source), + m_OpenMode(mode), + m_FirstModifiableLayerID(0) { + m_FirstModifiableLayerID = GetLayersCount(); } -otb::ogr::DataSource::Pointer otb::ogr::DataSource::CreateDataSourceFromDriver(std::string const& filename) +otb::ogr::DataSource::Pointer otb::ogr::DataSource::OpenDataSource(std::string const& datasourceName, Modes::type mode) { + bool update = (mode != Modes::Read); + + OGRDataSource * source = OGRSFDriverRegistrar::Open(datasourceName.c_str(), update); + if (!source) + { + // In read mode, this is a failure + // In write mode (Overwrite and Update), create the data source transparently + if (mode == Modes::Read) + { + itkGenericExceptionMacro(<< "Failed to open OGRDataSource file " + << datasourceName<<" : " << CPLGetLastErrorMsg()); + } + + // Hand made factory based on file extension. + char const* driverName = DeduceDriverName(datasourceName); + if (!driverName) + { + itkGenericExceptionMacro(<< "No OGR driver known to OTB to create and handle a DataSource named <" + <<datasourceName<<">."); + } + + OGRSFDriver * d = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driverName); + assert(d && "OGR driver not found"); + source = d->CreateDataSource(datasourceName.c_str()); + if (!source) { + itkGenericExceptionMacro(<< "Failed to create OGRDataSource <"<<datasourceName + <<"> (driver name: <" << driverName<<">: " << CPLGetLastErrorMsg()); + } + source->SetDriver(d); + } + return otb::ogr::DataSource::New(source, mode); + +#if 0 // Hand made factory based on file extension. char const* driverName = DeduceDriverName(filename); if (!driverName) @@ -150,16 +188,52 @@ otb::ogr::DataSource::Pointer otb::ogr::DataSource::CreateDataSourceFromDriver(s <<"> (driver name: " << driverName<<">: " << CPLGetLastErrorMsg()); } source->SetDriver(d); - otb::ogr::DataSource::Pointer res = new otb::ogr::DataSource(source); + otb::ogr::DataSource::Pointer res = new otb::ogr::DataSource(source, mode); res->UnRegister(); return res; +#endif +} + +void DeleteDataSource(std::string const& datasourceName) +{ + // Attempt to delete the datasource if it already exists + OGRDataSource * poDS = OGRSFDriverRegistrar::Open(datasourceName.c_str(), TRUE); + + if (poDS != NULL) + { + OGRSFDriver * ogrDriver = poDS->GetDriver(); + OGRDataSource::DestroyDataSource(poDS); + //Erase the data if possible + if (ogrDriver->TestCapability(ODrCDeleteDataSource)) + { + //Delete datasource + OGRErr ret = ogrDriver->DeleteDataSource(datasourceName.c_str()); + if (ret != OGRERR_NONE) + { + itkGenericOutputMacro(<< "Deletion of data source " << datasourceName + << " failed: " << CPLGetLastErrorMsg()); + } + } + else + { + itkGenericOutputMacro(<< "Cannot delete data source " << datasourceName); + } + } // if (poDS != NULL) } otb::ogr::DataSource::Pointer -otb::ogr::DataSource::New(std::string const& filename, Modes::type mode) +otb::ogr::DataSource::New(std::string const& datasourceName, Modes::type mode) { Drivers::Init(); + if (mode == Modes::Overwrite) + { + DeleteDataSource(datasourceName); + } + + return OpenDataSource(datasourceName, mode); + +#if 0 const bool write = mode & Modes::write; // std::cout << "Opening datasource " << filename << " update=" << update << "\n"; if (itksys::SystemTools::FileExists(filename.c_str())) @@ -227,13 +301,14 @@ otb::ogr::DataSource::New(std::string const& filename, Modes::type mode) } } return CreateDataSourceFromDriver(filename); +#endif } /*static*/ otb::ogr::DataSource::Pointer -otb::ogr::DataSource::New(OGRDataSource * source) +otb::ogr::DataSource::New(OGRDataSource * source, Modes::type mode) { - Pointer res = new DataSource(source); + Pointer res = new DataSource(source, mode); res->UnRegister(); return res; } @@ -273,6 +348,20 @@ otb::ogr::Layer otb::ogr::DataSource::CreateLayer( char ** papszOptions/* = NULL */) { assert(m_DataSource && "Datasource not initialized"); + + switch (m_OpenMode) + { + case Modes::Invalid: + assert(false && "Invalid OGRDataSource opening mode"); + itkGenericExceptionMacro(<< "Invalid OGRDataSource opening mode"); + break; + case Modes::Read: + itkGenericExceptionMacro(<< "OGRDataSource is opened in Read mode : cannot create a layer"); + break; + default: + break; + } + OGRLayer * ol = m_DataSource->CreateLayer( name.c_str(), poSpatialRef, eGType, papszOptions); if (!ol) @@ -281,7 +370,9 @@ otb::ogr::Layer otb::ogr::DataSource::CreateLayer( << "> in the OGRDataSource file <" << m_DataSource->GetName() <<">: " << CPLGetLastErrorMsg()); } - Layer l(ol/*, this*/); + + const bool modifiable = true; + Layer l(ol, modifiable); return l; } @@ -291,6 +382,20 @@ otb::ogr::Layer otb::ogr::DataSource::CopyLayer( char ** papszOptions/* = NULL */) { assert(m_DataSource && "Datasource not initialized"); + + switch (m_OpenMode) + { + case Modes::Invalid: + assert(false && "Invalid OGRDataSource opening mode"); + itkGenericExceptionMacro(<< "Invalid OGRDataSource opening mode"); + break; + case Modes::Read: + itkGenericExceptionMacro(<< "OGRDataSource is opened in Read mode : cannot create a layer"); + break; + default: + break; + } + OGRLayer * l0 = &srcLayer.ogr(); OGRLayer * ol = m_DataSource->CopyLayer(l0, newName.c_str(), papszOptions); if (!ol) @@ -300,12 +405,31 @@ otb::ogr::Layer otb::ogr::DataSource::CopyLayer( << "> in the OGRDataSource file <" << m_DataSource->GetName() <<">: " << CPLGetLastErrorMsg()); } - Layer l(ol/*, this*/); + const bool modifiable = true; + Layer l(ol, modifiable); return l; } void otb::ogr::DataSource::DeleteLayer(size_t i) { + assert(m_DataSource && "Datasource not initialized"); + + switch (m_OpenMode) + { + case Modes::Invalid: + assert(false && "Invalid OGRDataSource opening mode"); + itkGenericExceptionMacro(<< "Invalid OGRDataSource opening mode"); + break; + case Modes::Read: + itkGenericExceptionMacro(<< "OGRDataSource is opened in Read mode : cannot delete a layer"); + break; + case Modes::Update_LayerCreateOnly: + itkGenericExceptionMacro(<< "OGRDataSource is opened in Update_LayerCreateOnly mode : cannot delete a layer"); + break; + default: + break; + } + const int nb_layers = GetLayersCount(); if (int(i) >= nb_layers) { @@ -320,6 +444,49 @@ void otb::ogr::DataSource::DeleteLayer(size_t i) } } +bool otb::ogr::DataSource::IsLayerModifiable(size_t i) const +{ + switch(m_OpenMode) + { + case Modes::Read: + return false; + case Modes::Update_LayerCreateOnly: + return int(i) >= m_FirstModifiableLayerID; + default: + return true; + } +} + +bool otb::ogr::DataSource::IsLayerModifiable(std::string const& layername) const +{ + switch(m_OpenMode) + { + case Modes::Read: + return false; + case Modes::Update_LayerCreateOnly: + return int(GetLayerID(layername)) >= m_FirstModifiableLayerID; + default: + return true; + } +} + +size_t otb::ogr::DataSource::GetLayerID(std::string const& name) const +{ + for (int i = 0; + i < GetLayersCount(); + i++) + { + if (GetLayer(i).GetName() == name) + { + return i; + } + } + + itkExceptionMacro( << "Cannot fetch any layer named <" << name + << "> in the OGRDataSource <" << m_DataSource->GetName() << ">: " + << CPLGetLastErrorMsg()); + return 0; // keep compiler happy +} otb::ogr::Layer otb::ogr::DataSource::GetLayerChecked(size_t i) { @@ -335,7 +502,7 @@ otb::ogr::Layer otb::ogr::DataSource::GetLayerChecked(size_t i) itkExceptionMacro( << "Unexpected error: cannot fetch " << i << "th layer in the OGRDataSource <" << m_DataSource->GetName() << ">: " << CPLGetLastErrorMsg()); } - return otb::ogr::Layer(layer_ptr/*, this*/); + return otb::ogr::Layer(layer_ptr, IsLayerModifiable(i)); } OGRLayer* otb::ogr::DataSource::GetLayerUnchecked(size_t i) @@ -349,10 +516,9 @@ otb::ogr::Layer otb::ogr::DataSource::GetLayer(std::string const& name) { assert(m_DataSource && "Datasource not initialized"); OGRLayer * layer_ptr = m_DataSource->GetLayerByName(name.c_str()); - return otb::ogr::Layer(layer_ptr/*, this*/); + return otb::ogr::Layer(layer_ptr, IsLayerModifiable(name)); } - otb::ogr::Layer otb::ogr::DataSource::GetLayerChecked(std::string const& name) { assert(m_DataSource && "Datasource not initialized"); @@ -363,7 +529,7 @@ otb::ogr::Layer otb::ogr::DataSource::GetLayerChecked(std::string const& name) << "> in the OGRDataSource <" << m_DataSource->GetName() << ">: " << CPLGetLastErrorMsg()); } - return otb::ogr::Layer(layer_ptr/*, this*/); + return otb::ogr::Layer(layer_ptr, IsLayerModifiable(name)); } int otb::ogr::DataSource::GetLayersCount() const @@ -378,6 +544,7 @@ otb::ogr::Layer otb::ogr::DataSource::ExecuteSQL( char const* pszDialect) { assert(m_DataSource && "Datasource not initialized"); + const bool modifiable = false; OGRLayer * layer_ptr = m_DataSource->ExecuteSQL( statement.c_str(), poSpatialFilter, pszDialect); if (!layer_ptr) @@ -389,10 +556,11 @@ otb::ogr::Layer otb::ogr::DataSource::ExecuteSQL( // Cannot use the deleter made for result sets obtained from // OGRDataSource::ExecuteSQL because it checks for non-nullity.... // *sigh* - return otb::ogr::Layer(0/*, 0*/); + + return otb::ogr::Layer(0, modifiable); #endif } - return otb::ogr::Layer(layer_ptr, *m_DataSource); + return otb::ogr::Layer(layer_ptr, *m_DataSource, modifiable); } diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h index 19146ffb5267dafd3afc2a92caa76e2e6855b10c..ca8b120a051fc5f6d8e01dbec422ea96c33ab781 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h @@ -85,7 +85,7 @@ public: * \see \c DataSource() */ itkNewMacro(Self); - itkTypeMacro(Layer, DataObject); + itkTypeMacro(DataSource, DataObject); //@} /**\name Creation functions */ //@{ @@ -94,11 +94,38 @@ public: * \note Read/Write mode should have been <tt>read | write</tt>, but actually * OGR data source are always at least in read mode. */ - struct Modes { enum type { invalid, read=1, write=2, append=4, MAX__ }; }; + struct Modes { + enum type + { + Invalid, + Read, ///< Open data source in read-only mode + Overwrite, ///< Open data source in overwrite mode + ///< + ///< Data source is deleted if it exists + ///< and a new data source is created + ///< Warning : this can delete a whole database + ///< if the existing datasource contains a list of layers + Update_LayerOverwrite, ///< Open data source in update mode with layers being overwritten + ///< + ///< When requesting a layer, it is opened in overwrite mode + ///< with OVERWRITE=YES creation option. + ///< If the layer does not exists, it is created on the fly + Update_LayerUpdate, ///< Open data source in update mode with layers being updated + ///< + ///< New geometries are added to existing layers. + ///< If the layer does not exists, it is created on the fly + Update_LayerCreateOnly,///< Open data source in update mode with layers being created only + ///< + ///< This option prevents the loss of data. + ///< One can open an existing database with existing layer, and + ///< and add new layers to it. + ///< Only non-existing layers can be requested + MAX__ }; + }; /** * Builder from an existing named data source. - * \param[in] filename filename of the data source + * \param[in] datasourcename OGR identifier of the data source * \param[in] mode opening mode (read or read-write) * \return a newly created \c DataSource. * \throw itk::ExceptionObject if the inner \c OGRDataSource cannot be @@ -106,7 +133,7 @@ public: * \note \c OGRRegisterAll() is implicitly called on construction * \see \c DataSource(OGRDataSource *) */ - static Pointer New(std::string const& filename, Modes::type mode=Modes::read); + static Pointer New(std::string const& datasourcename, Modes::type mode = Modes::Read); /** * Builder from a built \c OGRDataSource. * \param[in,out] source \c OGRDataSource already constructed. @@ -118,7 +145,7 @@ public: * \note No condition is assumed on the non-nullity of \c source. * \see \c DataSource(OGRDataSource *) */ - static Pointer New(OGRDataSource * source); + static Pointer New(OGRDataSource * sourcemode, Modes::type mode = Modes::Read); //@} /**\name Projection Reference property */ @@ -465,13 +492,13 @@ protected: /** Init constructor. * \post The newly constructed object owns the \c source parameter. */ - DataSource(OGRDataSource * source); + DataSource(OGRDataSource * source, Modes::type mode); /** Destructor. * \post The \c OGRDataSource owned is released (if not null). */ virtual ~DataSource(); - static Pointer CreateDataSourceFromDriver(std::string const& filename); + static Pointer OpenDataSource(std::string const& datasourceName, Modes::type mode); /** Prints self into stream. */ virtual void PrintSelf(std::ostream& os, itk::Indent indent) const; @@ -492,9 +519,16 @@ private: */ OGRLayer* GetLayerUnchecked(size_t i) const; + bool IsLayerModifiable(size_t i) const; + + bool IsLayerModifiable(std::string const& name) const; + + size_t GetLayerID(std::string const& name) const; + private: OGRDataSource *m_DataSource; - // ImageReference m_ImageReference; + Modes::type m_OpenMode; + int m_FirstModifiableLayerID; }; // end class DataSource } } // end namespace otb::ogr diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.txx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.txx index fc69791aa99176627e25b6f16b652689db0060a2..d9f240e07872467c2eb34c996e016326cbe6a740 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.txx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.txx @@ -50,7 +50,7 @@ otb::ogr::Layer otb::ogr::DataSource::GetLayer(size_t i) assert(int(i) < GetLayersCount() && "Out-of-range index"); OGRLayer * layer_ptr = GetLayerUnchecked(i); assert(layer_ptr && "No layer returned by OGR"); - return otb::ogr::Layer(layer_ptr/*, this*/); + return otb::ogr::Layer(layer_ptr, IsLayerModifiable(i)); } inline @@ -123,7 +123,7 @@ Value otb::ogr::DataSource::layer_iter<Value>::dereference() const assert(m_DataSource && int(m_index) < m_DataSource->GetLayersCount() && "cannot dereference past end()"); - return Value(m_DataSource->GetLayerUnchecked(m_index)/*, const_cast <DataSource*>(m_DataSource)*/); + return Value(m_DataSource->GetLayerUnchecked(m_index), m_DataSource->IsLayerModifiable(m_index)); } diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRGeometriesVisitor.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRGeometriesVisitor.h index 0bda05e262c7b3629958581aaad02c51ce4f6b6e..9fe09282ab3c2a330079be5e075972f76aa44a66 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRGeometriesVisitor.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRGeometriesVisitor.h @@ -83,6 +83,7 @@ TResult apply(TGeometry * geometry, TFunctor functor) { // functor(geometry); } + return TResult(); // keep compiler happy } } // ogr namespace diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx index e5108ee61d8230acb8a0eb87c85be498cb9beee8..39cf4960ad1151334d8cc068a575fd3938007160 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx @@ -44,16 +44,18 @@ namespace { // Anonymous namespace } // Anonymous namespace -otb::ogr::Layer::Layer(OGRLayer* layer/*, DataSourcePtr datasource*/) -: m_Layer(layer, LeaveAloneDeleter()) +otb::ogr::Layer::Layer(OGRLayer* layer, bool modifiable) +: m_Layer(layer, LeaveAloneDeleter()) + , m_Modifiable(modifiable) #if 0 , m_DataSource(datasource) #endif { } -otb::ogr::Layer::Layer(OGRLayer* layer, OGRDataSource& sourceInChargeOfLifeTime) -: m_Layer(layer, boost::bind(&OGRDataSource::ReleaseResultSet, boost::ref(sourceInChargeOfLifeTime), _1)) +otb::ogr::Layer::Layer(OGRLayer* layer, OGRDataSource& sourceInChargeOfLifeTime, bool modifiable) +: m_Layer(layer, boost::bind(&OGRDataSource::ReleaseResultSet, boost::ref(sourceInChargeOfLifeTime), _1)) + , m_Modifiable(modifiable) { assert(layer && "A null OGRlayer cannot belong to an OGRDataSource" ); // OGR always refuses "delete 0". *sigh* @@ -106,6 +108,13 @@ otb::ogr::Layer::const_iterator otb::ogr::Layer::cstart_at(size_t index) const void otb::ogr::Layer::CreateFeature(Feature feature) { assert(m_Layer && "OGRLayer not initialized"); + + if (!m_Modifiable) + { + itkGenericExceptionMacro(<< "Cannot create a new feature in the layer <" + <<GetName()<<">: layer is not modifiable"); + } + const OGRErr res = m_Layer->CreateFeature(&feature.ogr()); if (res != OGRERR_NONE) { @@ -117,6 +126,13 @@ void otb::ogr::Layer::CreateFeature(Feature feature) void otb::ogr::Layer::DeleteFeature(long nFID) { assert(m_Layer && "OGRLayer not initialized"); + + if (!m_Modifiable) + { + itkGenericExceptionMacro(<< "Cannot create a new feature in the layer <" + <<GetName()<<">: layer is not modifiable"); + } + const OGRErr res = m_Layer->DeleteFeature(nFID); if (res != OGRERR_NONE) { @@ -139,6 +155,13 @@ otb::ogr::Feature otb::ogr::Layer::GetFeature(long nFID) void otb::ogr::Layer::SetFeature(Feature feature) { assert(m_Layer && "OGRLayer not initialized"); + + if (!m_Modifiable) + { + itkGenericExceptionMacro(<< "Cannot create a new feature in the layer <" + <<GetName()<<">: layer is not modifiable"); + } + const OGRErr res = m_Layer->SetFeature(&feature.ogr()); if (res != OGRERR_NONE) { @@ -275,6 +298,13 @@ void otb::ogr::Layer::CreateField( FieldDefn const& field, bool bApproxOK/* = true */) { assert(m_Layer && "OGRLayer not initialized"); + + if (!m_Modifiable) + { + itkGenericExceptionMacro(<< "Cannot create a new field in the layer <" + <<GetName()<<">: layer is not modifiable"); + } + const OGRErr res = m_Layer->CreateField(&field.ogr(), bApproxOK); if (res != OGRERR_NONE) { @@ -286,6 +316,13 @@ void otb::ogr::Layer::CreateField( void otb::ogr::Layer::DeleteField(size_t fieldIndex) { assert(m_Layer && "OGRLayer not initialized"); + + if (!m_Modifiable) + { + itkGenericExceptionMacro(<< "Cannot delete field in the layer <" + <<GetName()<<">: layer is not modifiable"); + } + #if GDAL_VERSION_NUM < 1900 itkGenericExceptionMacro("OGRLayer::DeleteField is not supported by OGR v" << GDAL_VERSION_NUM << ". Upgrade to a version >= 1.9.0, and recompile OTB.") @@ -303,6 +340,13 @@ void otb::ogr::Layer::AlterFieldDefn( size_t fieldIndex, FieldDefn const& newFieldDefn, int nFlags) { assert(m_Layer && "OGRLayer not initialized"); + + if (!m_Modifiable) + { + itkGenericExceptionMacro(<< "Cannot alter field definition in the layer <" + <<GetName()<<">: layer is not modifiable"); + } + #if GDAL_VERSION_NUM < 1900 itkGenericExceptionMacro("OGRLayer::AlterFieldDefn is not supported by OGR v" << GDAL_VERSION_NUM << ". Upgrade to a version >= 1.9.0, and recompile OTB.") @@ -322,6 +366,13 @@ void otb::ogr::Layer::AlterFieldDefn( void otb::ogr::Layer::ReorderField(size_t oldPos, size_t newPos) { assert(m_Layer && "OGRLayer not initialized"); + + if (!m_Modifiable) + { + itkGenericExceptionMacro(<< "Cannot reorder fields in the layer <" + <<GetName()<<">: layer is not modifiable"); + } + #if GDAL_VERSION_NUM < 1900 itkGenericExceptionMacro("OGRLayer::ReorderField is not supported by OGR v" << GDAL_VERSION_NUM << ". Upgrade to a version >= 1.9.0, and recompile OTB.") @@ -338,6 +389,13 @@ void otb::ogr::Layer::ReorderField(size_t oldPos, size_t newPos) void otb::ogr::Layer::ReorderFields(int * map) { assert(m_Layer && "OGRLayer not initialized"); + + if (!m_Modifiable) + { + itkGenericExceptionMacro(<< "Cannot reorder fields in the layer <" + <<GetName()<<">: layer is not modifiable"); + } + #if GDAL_VERSION_NUM < 1900 itkGenericExceptionMacro("OGRLayer::ReorderField is not supported by OGR v" << GDAL_VERSION_NUM << ". Upgrade to a version >= 1.9.0, and recompile OTB.") diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h index 1071ab001289d41e76bbd500703377e3a335df42..97ec2e1872b2cc3bc4f2ed4e0d05886c49d034c9 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h @@ -87,7 +87,7 @@ public: * is deleted, the layer won't be usable anymore. Unfortunatelly, there is no * mean to report this to this layer proxy. */ - Layer(OGRLayer* layer/*, DataSourcePtr datasource*/); + Layer(OGRLayer* layer, bool modifiable); /** * Init constructor for layers that need to be released. @@ -103,7 +103,7 @@ public: * OGRDataSource::ExecuteSQL(). It's actually the constructor called by \c * DataSource::ExecuteSQL(). */ - Layer(OGRLayer* layer, OGRDataSource& sourceInChargeOfLifeTime); + Layer(OGRLayer* layer, OGRDataSource& sourceInChargeOfLifeTime, bool modifiable); //@} /**\name Features collection */ @@ -516,6 +516,8 @@ private: */ boost::shared_ptr<OGRLayer> m_Layer; + bool m_Modifiable; + #if 0 /** Related DataSource. * Needed to acces OTB meta informations. diff --git a/Examples/Filtering/GeometriesChangeSpatialReference.cxx b/Examples/Filtering/GeometriesChangeSpatialReference.cxx index b79fc20ec9d85bcaffbddd2ce12dbb383598878b..661a2815192d1e376b0c0604e542c18b181d0928 100644 --- a/Examples/Filtering/GeometriesChangeSpatialReference.cxx +++ b/Examples/Filtering/GeometriesChangeSpatialReference.cxx @@ -145,12 +145,12 @@ int main (int argc, char **argv) otb::ogr::DataSource::Pointer input = otb::ogr::DataSource::New( options.inputFile, - options.workingInplace ? otb::ogr::DataSource::Modes::write : otb::ogr::DataSource::Modes::read); + options.workingInplace ? otb::ogr::DataSource::Modes::Update_LayerOverwrite : otb::ogr::DataSource::Modes::Read); otb::ogr::DataSource::Pointer output = options.workingInplace ? input : options.outputIsStdout ? 0 - : otb::ogr::DataSource::New( options.outputFile, otb::ogr::DataSource::Modes::write); + : otb::ogr::DataSource::New( options.outputFile, otb::ogr::DataSource::Modes::Update_LayerCreateOnly); std::cout << "input: " << input -> ogr().GetName() << " should be: " << options.inputFile << "\n"; if (output) { diff --git a/Examples/Filtering/GeometriesFilter.cxx b/Examples/Filtering/GeometriesFilter.cxx index f0464f999cc826a9fd3a9c8bd41e68c4c848bdce..9847384479e8c765f5758c207bdf2d3b1cbb40f6 100644 --- a/Examples/Filtering/GeometriesFilter.cxx +++ b/Examples/Filtering/GeometriesFilter.cxx @@ -68,12 +68,12 @@ int main (int argc, char **argv) otb::ogr::DataSource::Pointer input = otb::ogr::DataSource::New( inputFile, - workingInplace ? otb::ogr::DataSource::Modes::write : otb::ogr::DataSource::Modes::read); + workingInplace ? otb::ogr::DataSource::Modes::Update_LayerOverwrite : otb::ogr::DataSource::Modes::Read); otb::ogr::DataSource::Pointer output = workingInplace ? input : outputIsStdout ? 0 - : otb::ogr::DataSource::New( outputFile, otb::ogr::DataSource::Modes::write); + : otb::ogr::DataSource::New( outputFile, otb::ogr::DataSource::Modes::Update_LayerCreateOnly); std::cout << "input: " << input -> ogr().GetName() << " should be: " << inputFile << "\n"; if (output) { diff --git a/Examples/IO/OGRWrappersExample.cxx b/Examples/IO/OGRWrappersExample.cxx index ffacfc3cbc7ae176fd86ad7adf7fa9cda9578068..94ff1823b23c8b06bec7c0d4a68875dd92e832c2 100644 --- a/Examples/IO/OGRWrappersExample.cxx +++ b/Examples/IO/OGRWrappersExample.cxx @@ -94,7 +94,7 @@ int main(int argc, char * argv[]) // Software Guide : EndLatex // Software Guide : BeginCodeSnippet otb::ogr::DataSource::Pointer source = otb::ogr::DataSource::New( - argv[1], otb::ogr::DataSource::Modes::read); + argv[1], otb::ogr::DataSource::Modes::Read); // Software Guide : EndCodeSnippet // Software Guide : BeginLatex // @@ -104,7 +104,7 @@ int main(int argc, char * argv[]) // Software Guide : EndLatex // Software Guide : BeginCodeSnippet otb::ogr::DataSource::Pointer destination = otb::ogr::DataSource::New( - argv[2], otb::ogr::DataSource::Modes::write); + argv[2], otb::ogr::DataSource::Modes::Update_LayerCreateOnly); otb::ogr::Layer destLayer = destination->CreateLayer( argv[2], 0, wkbMultiPolygon); // Software Guide : EndCodeSnippet diff --git a/Examples/Projections/GeometriesProjection.cxx b/Examples/Projections/GeometriesProjection.cxx index f46a84afb0aeaa10a076a75034cd74126a8dae77..20304f2f014e6d8fce0a42387f3edf7c3358c039 100644 --- a/Examples/Projections/GeometriesProjection.cxx +++ b/Examples/Projections/GeometriesProjection.cxx @@ -72,7 +72,7 @@ int main(int argc, char* argv[]) // Software Guide : BeginCodeSnippet otb::ogr::DataSource::Pointer input = otb::ogr::DataSource::New( - argv[1], otb::ogr::DataSource::Modes::read); + argv[1], otb::ogr::DataSource::Modes::Read); InputGeometriesType::Pointer in_set = InputGeometriesType::New(input); // Software Guide : EndCodeSnippet @@ -141,7 +141,7 @@ int main(int argc, char* argv[]) // Software Guide : BeginCodeSnippet otb::ogr::DataSource::Pointer output = otb::ogr::DataSource::New( - argv[3], otb::ogr::DataSource::Modes::write); + argv[3], otb::ogr::DataSource::Modes::Update_LayerCreateOnly); OutputGeometriesType::Pointer out_set = OutputGeometriesType::New(output); filter->SetOutput(out_set); diff --git a/Examples/Segmentation/StreamingMeanShiftSegmentation.cxx b/Examples/Segmentation/StreamingMeanShiftSegmentation.cxx index f7899825b454e235ca94c4875c3c5a37838c099f..53c09a240618d9141209bab0dce6476f98932758 100644 --- a/Examples/Segmentation/StreamingMeanShiftSegmentation.cxx +++ b/Examples/Segmentation/StreamingMeanShiftSegmentation.cxx @@ -135,7 +135,7 @@ int main(int argc, char *argv[]) // Here we used a non existing filename to create a new file in writing mode. // Software Guide : EndLatex // Software Guide : BeginCodeSnippet - otb::ogr::DataSource::Pointer ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::write); + otb::ogr::DataSource::Pointer ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Update_LayerCreateOnly); // Software Guide : EndCodeSnippet diff --git a/Testing/Code/Common/otbOGRDataSourceToLabelImageFilter.cxx b/Testing/Code/Common/otbOGRDataSourceToLabelImageFilter.cxx index 081ea18e0cd6857d76282306b028c3f9be7b8aae..59fdb198f4e998ec6ff49a6c697bf22a3c54cb11 100644 --- a/Testing/Code/Common/otbOGRDataSourceToLabelImageFilter.cxx +++ b/Testing/Code/Common/otbOGRDataSourceToLabelImageFilter.cxx @@ -49,7 +49,7 @@ int otbOGRDataSourceToLabelImageFilter(int argc, char* argv[]) unsigned char background = atoi(argv[5]); unsigned char foreground = atoi(argv[6]); - otb::ogr::DataSource::Pointer ogrDS = otb::ogr::DataSource::New(argv[2], otb::ogr::DataSource::Modes::read); + otb::ogr::DataSource::Pointer ogrDS = otb::ogr::DataSource::New(argv[2], otb::ogr::DataSource::Modes::Read); // rasterize RasterizationFilterType::Pointer rasterization = RasterizationFilterType::New(); diff --git a/Testing/Code/Projections/otbGeometriesProjectionFilter.cxx b/Testing/Code/Projections/otbGeometriesProjectionFilter.cxx index 0041185ff63af71a2f4b20f41a43ff6aed1c812e..1232e6e60055df0eb34ff7d3bf26c86023074b4a 100644 --- a/Testing/Code/Projections/otbGeometriesProjectionFilter.cxx +++ b/Testing/Code/Projections/otbGeometriesProjectionFilter.cxx @@ -38,7 +38,7 @@ int otbGeometriesProjectionFilter(int argc, char * argv[]) typedef otb::GeometriesSet InputGeometriesType; typedef otb::GeometriesSet OutputGeometriesType; otb::ogr::DataSource::Pointer input = otb::ogr::DataSource::New( - argv[1], otb::ogr::DataSource::Modes::read); + argv[1], otb::ogr::DataSource::Modes::Read); InputGeometriesType::Pointer in_set = InputGeometriesType::New(input); typedef otb::GeometriesProjectionFilter GeometriesFilterType; @@ -54,7 +54,7 @@ int otbGeometriesProjectionFilter(int argc, char * argv[]) otb::StandardFilterWatcher watcher(filter, "GeometriesProjection"); otb::ogr::DataSource::Pointer output = otb::ogr::DataSource::New( - argv[2], otb::ogr::DataSource::Modes::write); + argv[2], otb::ogr::DataSource::Modes::Update_LayerCreateOnly); OutputGeometriesType::Pointer out_set = OutputGeometriesType::New(output); filter->SetOutput(out_set); diff --git a/Testing/Code/Projections/otbGeometriesProjectionFilterFromMapToEPSG.cxx b/Testing/Code/Projections/otbGeometriesProjectionFilterFromMapToEPSG.cxx index beb5907906e5bb3a0ab6d27dc407edd7c443602b..a89963b96302071eb5167ea394a686b44582e8ba 100644 --- a/Testing/Code/Projections/otbGeometriesProjectionFilterFromMapToEPSG.cxx +++ b/Testing/Code/Projections/otbGeometriesProjectionFilterFromMapToEPSG.cxx @@ -36,7 +36,7 @@ int otbGeometriesProjectionFilterFromMapToEPSG(int argc, char * argv[]) typedef otb::GeometriesSet OutputGeometriesType; otb::ogr::DataSource::Pointer input = otb::ogr::DataSource::New( - inputVDFilename, otb::ogr::DataSource::Modes::read); + inputVDFilename, otb::ogr::DataSource::Modes::Read); InputGeometriesType::Pointer in_set = InputGeometriesType::New(input); typedef otb::GeometriesProjectionFilter GeometriesFilterType; @@ -46,7 +46,7 @@ int otbGeometriesProjectionFilterFromMapToEPSG(int argc, char * argv[]) filter->SetOutputProjectionRef( otb::GeoInformationConversion::ToWKT(epsg) ); otb::ogr::DataSource::Pointer output = otb::ogr::DataSource::New( - outputVDFilename, otb::ogr::DataSource::Modes::write); + outputVDFilename, otb::ogr::DataSource::Modes::Overwrite); OutputGeometriesType::Pointer out_set = OutputGeometriesType::New(output); filter->SetOutput(out_set); diff --git a/Testing/Code/Segmentation/otbOGRDataSourceStreamStitchingFilter.cxx b/Testing/Code/Segmentation/otbOGRDataSourceStreamStitchingFilter.cxx index 7e88dfdbc9bffff024a05b0fd13131e00a5115e6..d60323ac934f3b5aebadfc327f323d9528137a5c 100644 --- a/Testing/Code/Segmentation/otbOGRDataSourceStreamStitchingFilter.cxx +++ b/Testing/Code/Segmentation/otbOGRDataSourceStreamStitchingFilter.cxx @@ -76,7 +76,7 @@ int otbOGRDataSourceStreamStitchingFilter(int argc, char * argv[]) ImageType::SizeType streamSize; streamSize.Fill(size); - otb::ogr::DataSource::Pointer ogrDS = otb::ogr::DataSource::New(tmpOGRfname, otb::ogr::DataSource::Modes::append); + otb::ogr::DataSource::Pointer ogrDS = otb::ogr::DataSource::New(tmpOGRfname, otb::ogr::DataSource::Modes::Update_LayerUpdate); filter->SetInput(reader->GetOutput()); filter->SetOGRDataSource(ogrDS); diff --git a/Testing/Code/Segmentation/otbStreamingImageToOGRLayerSegmentationFilter.cxx b/Testing/Code/Segmentation/otbStreamingImageToOGRLayerSegmentationFilter.cxx index cbbdaa458b3ddb7cec6a1bd244c069f4870d2457..dc8f40d2c273808699c44c1d2be79b6fb34cc087 100644 --- a/Testing/Code/Segmentation/otbStreamingImageToOGRLayerSegmentationFilter.cxx +++ b/Testing/Code/Segmentation/otbStreamingImageToOGRLayerSegmentationFilter.cxx @@ -98,7 +98,7 @@ int otbStreamingImageToOGRLayerSegmentationFilter(int argc, char * argv[]) // Create the output data-source in overwrite mode // TODO: Change once flags have been updated - otb::ogr::DataSource::Pointer ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::write); + otb::ogr::DataSource::Pointer ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Overwrite); OGRSpatialReference oSRS(reader->GetOutput()->GetProjectionRef().c_str()); diff --git a/Testing/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapperNew.cxx b/Testing/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapperNew.cxx index 7bea7af4fb3f37a6ca658ec5819a476b412faa89..cac199c2d06e9abaa653ed0b491b167476a006b1 100644 --- a/Testing/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapperNew.cxx +++ b/Testing/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapperNew.cxx @@ -108,9 +108,9 @@ BOOST_AUTO_TEST_CASE(OGRDataSource_mem_add_n_del_layer) BOOST_AUTO_TEST_CASE(OGRDataSource_new_exceptions) { - BOOST_CHECK_THROW(ogr::DataSource::New("name-that-shall-not-exist.shp", ogr::DataSource::Modes::read), + BOOST_CHECK_THROW(ogr::DataSource::New("name-that-shall-not-exist.shp", ogr::DataSource::Modes::Read), itk::ExceptionObject); - BOOST_CHECK_THROW(ogr::DataSource::New("unsupported.extension", ogr::DataSource::Modes::write), + BOOST_CHECK_THROW(ogr::DataSource::New("unsupported.extension", ogr::DataSource::Modes::Overwrite), itk::ExceptionObject) } @@ -118,7 +118,7 @@ BOOST_AUTO_TEST_CASE(OGRDataSource_new_shp) { const std::string k_shp = "SomeShapeFile"; const std::string k_one = k_shp; - ogr::DataSource::Pointer ds = ogr::DataSource::New(k_shp+".shp", ogr::DataSource::Modes::write); + ogr::DataSource::Pointer ds = ogr::DataSource::New(k_shp+".shp", ogr::DataSource::Modes::Overwrite); BOOST_CHECK_EQUAL(ds->GetLayersCount(), 0); ogr::Layer l = ds -> CreateLayer(k_one); @@ -301,7 +301,7 @@ BOOST_AUTO_TEST_CASE(OGRDataSource_new_shp_with_features) { const std::string k_shp = "SomeShapeFileWithFeatures"; const std::string k_one = k_shp; - ogr::DataSource::Pointer ds = ogr::DataSource::New(k_shp+".shp", ogr::DataSource::Modes::write); + ogr::DataSource::Pointer ds = ogr::DataSource::New(k_shp+".shp", ogr::DataSource::Modes::Overwrite); ogr::Layer l = ds -> CreateLayer(k_one, 0, wkbPoint);