Commit d5c00f86 authored by Julien Malik's avatar Julien Malik

ENH: clarify OGRDataSource opening mode, now containing the layer creation/update capability

parent 20301404
......@@ -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 = "";
......
......@@ -437,7 +437,7 @@ private:
{
// Retrieve output filename as well as layer names
std::string dataSourceName = GetParameterString("mode.vector.out");
ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::write);
ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Update_LayerOverwrite);
}
// The actual stream size used
......
......@@ -114,7 +114,8 @@ char const* DeduceDriverName(std::string filename)
otb::ogr::DataSource::DataSource()
: m_DataSource(0)
: m_DataSource(0),
m_OpenMode(Modes::Update_LayerOverwrite)
{
Drivers::Init();
......@@ -127,13 +128,47 @@ 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)
{
}
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 +185,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 +298,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;
}
......
......@@ -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_LayerAppend, ///< 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;
......@@ -494,7 +521,7 @@ private:
private:
OGRDataSource *m_DataSource;
// ImageReference m_ImageReference;
Modes::type m_OpenMode;
}; // end class DataSource
} } // end namespace otb::ogr
......
......@@ -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)
{
......
......@@ -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)
{
......
......@@ -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
......
......@@ -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);
......
......@@ -129,7 +129,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
// Software Guide : BeginLatex
......
......@@ -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();
......
......@@ -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);
......
......@@ -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);
......
......@@ -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_LayerAppend);
filter->SetInput(reader->GetOutput());
filter->SetOGRDataSource(ogrDS);
......
......@@ -96,7 +96,7 @@ int otbStreamingImageToOGRDataSourceSegmentationFilter(int argc, char * argv[])
maskReader->SetFileName(maskName);
maskReader->UpdateOutputInformation();
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);
filter->SetInput(reader->GetOutput());
filter->SetInputMask(maskReader->GetOutput());
......
......@@ -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);
......
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