Commit 2ba8dc03 authored by Julien Malik's avatar Julien Malik

ENH: filter layer operation depending on DataSource open mode

parent 5614f84b
......@@ -115,7 +115,8 @@ char const* DeduceDriverName(std::string filename)
otb::ogr::DataSource::DataSource()
: m_DataSource(0),
m_OpenMode(Modes::Update_LayerOverwrite)
m_OpenMode(Modes::Update_LayerOverwrite),
m_FirstModifiableLayerID(0)
{
Drivers::Init();
......@@ -130,8 +131,10 @@ otb::ogr::DataSource::DataSource()
otb::ogr::DataSource::DataSource(OGRDataSource * source, Modes::type mode)
: m_DataSource(source),
m_OpenMode(mode)
m_OpenMode(mode),
m_FirstModifiableLayerID(0)
{
m_FirstModifiableLayerID = GetLayersCount();
}
otb::ogr::DataSource::Pointer otb::ogr::DataSource::OpenDataSource(std::string const& datasourceName, Modes::type mode)
......@@ -345,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)
......@@ -353,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;
}
......@@ -363,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)
......@@ -372,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)
{
......@@ -392,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)
{
......@@ -407,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)
......@@ -421,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");
......@@ -435,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
......@@ -450,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)
......@@ -461,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);
}
......
......@@ -110,7 +110,7 @@ public:
///< 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_LayerAppend, ///< Open data source in update mode with layers being updated
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
......@@ -519,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;
Modes::type m_OpenMode;
int m_FirstModifiableLayerID;
}; // end class DataSource
} } // end namespace otb::ogr
......
......@@ -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));
}
......
......@@ -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.")
......
......@@ -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.
......
......@@ -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::Update_LayerAppend);
otb::ogr::DataSource::Pointer ogrDS = otb::ogr::DataSource::New(tmpOGRfname, otb::ogr::DataSource::Modes::Update_LayerUpdate);
filter->SetInput(reader->GetOutput());
filter->SetOGRDataSource(ogrDS);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment