Commit 88f8ef09 authored by Guillaume Pasero's avatar Guillaume Pasero

BUG: fix ordering of output samples wrt multithreading

parent 77efa3b9
......@@ -139,6 +139,9 @@ protected:
*/
void DispatchInputVectors(void) ITK_OVERRIDE;
/** Fill the output vectors with a special ordering (class partition) */
void FillOneOutput(unsigned int outIdx, ogr::DataSource* outDS, bool update) ITK_OVERRIDE;
private:
PersistentOGRDataToSamplePositionFilter(const Self &); //purposely not implemented
void operator =(const Self&); //purposely not implemented
......
......@@ -308,6 +308,55 @@ PersistentOGRDataToSamplePositionFilter<TInputImage,TMaskImage,TSampler>
}
}
template<class TInputImage, class TMaskImage, class TSampler>
void
PersistentOGRDataToSamplePositionFilter<TInputImage,TMaskImage,TSampler>
::FillOneOutput(unsigned int outIdx, ogr::DataSource* outDS, bool update)
{
ogr::Layer outLayer = outDS->GetLayersCount() == 1
? outDS->GetLayer(0)
: outDS->GetLayer(this->GetOutLayerName());
OGRErr err = outLayer.ogr().StartTransaction();
if (err != OGRERR_NONE)
{
itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << ".");
}
// output vectors sorted by class
for (auto& label : m_ClassPartition)
{
ogr::Layer inLayer = this->GetInMemoryOutput(label.second,outIdx);
if (!inLayer)
{
continue;
}
// This test only uses 1 input, not compatible with multiple OGRData inputs
for(auto tmpIt = inLayer.begin(); tmpIt!=inLayer.end(); ++tmpIt)
{
if( label.first.compare(tmpIt->ogr().GetFieldAsString(this->GetFieldIndex())) != 0 )
continue;
if(update)
{
outLayer.SetFeature( *tmpIt );
}
else
{
ogr::Feature dstFeature(outLayer.GetLayerDefn());
dstFeature.SetFrom( *tmpIt, TRUE );
outLayer.CreateFeature( dstFeature );
}
}
}
err = outLayer.ogr().CommitTransaction();
if (err != OGRERR_NONE)
{
itkExceptionMacro(<< "Unable to commit transaction for OGR layer " << outLayer.ogr().GetName() << ".");
}
}
// -------------- otb::OGRDataToSamplePositionFilter --------------------------
template<class TInputImage, class TMaskImage, class TSampler>
......
......@@ -165,6 +165,9 @@ protected:
/** Gather the content of in-memory output layer into the filter outputs */
virtual void GatherOutputVectors(void);
/** Fill output vectors for a particular output */
virtual void FillOneOutput(unsigned int outIdx, ogr::DataSource* outDS, bool update);
/** Utility method to add new fields on an output layer */
virtual void InitializeOutputDataSource(ogr::DataSource* inputDS, ogr::DataSource* outputDS);
......
......@@ -275,8 +275,6 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
// clean temporary inputs
this->m_InMemoryInputs.clear();
unsigned int numberOfThreads = this->GetNumberOfThreads();
// gather temporary outputs and write to output
const otb::ogr::DataSource* vectors = this->GetOGRData();
otb::Stopwatch chrono = otb::Stopwatch::StartNew();
......@@ -287,58 +285,67 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
this->itk::ProcessObject::GetOutput(k));
if (realOutput)
{
ogr::Layer outLayer = realOutput->GetLayersCount() == 1
? realOutput->GetLayer(0)
: realOutput->GetLayer(m_OutLayerName);
this->FillOneOutput(count, realOutput, bool(vectors == realOutput));
count++;
}
}
OGRErr err = outLayer.ogr().StartTransaction();
if (err != OGRERR_NONE)
{
itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << ".");
}
chrono.Stop();
otbMsgDebugMacro(<< "Writing OGR points took " << chrono.GetElapsedMilliseconds() << " ms");
this->m_InMemoryOutputs.clear();
}
for (unsigned int thread=0 ; thread < numberOfThreads ; thread++)
{
ogr::Layer inLayer = this->m_InMemoryOutputs[thread][count]->GetLayerChecked(0);
if (!inLayer)
{
continue;
}
template <class TInputImage, class TMaskImage>
void
PersistentSamplingFilterBase<TInputImage,TMaskImage>
::FillOneOutput(unsigned int outIdx, ogr::DataSource* outDS, bool update)
{
ogr::Layer outLayer = outDS->GetLayersCount() == 1
? outDS->GetLayer(0)
: outDS->GetLayer(m_OutLayerName);
ogr::Layer::const_iterator tmpIt = inLayer.begin();
// This test only uses 1 input, not compatible with multiple OGRData inputs
if (vectors == realOutput)
{
// Update mode
for(; tmpIt!=inLayer.end(); ++tmpIt)
{
outLayer.SetFeature( *tmpIt );
}
}
else
{
// Copy mode
for(; tmpIt!=inLayer.end(); ++tmpIt)
{
ogr::Feature dstFeature(outLayer.GetLayerDefn());
dstFeature.SetFrom( *tmpIt, TRUE );
outLayer.CreateFeature( dstFeature );
}
}
}
OGRErr err = outLayer.ogr().StartTransaction();
if (err != OGRERR_NONE)
{
itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << ".");
}
err = outLayer.ogr().CommitTransaction();
if (err != OGRERR_NONE)
unsigned int numberOfThreads = this->GetNumberOfThreads();
for (unsigned int thread=0 ; thread < numberOfThreads ; thread++)
{
ogr::Layer inLayer = this->m_InMemoryOutputs[thread][outIdx]->GetLayerChecked(0);
if (!inLayer)
{
continue;
}
ogr::Layer::const_iterator tmpIt = inLayer.begin();
// This test only uses 1 input, not compatible with multiple OGRData inputs
if (update)
{
// Update mode
for(; tmpIt!=inLayer.end(); ++tmpIt)
{
itkExceptionMacro(<< "Unable to commit transaction for OGR layer " << outLayer.ogr().GetName() << ".");
outLayer.SetFeature( *tmpIt );
}
}
else
{
// Copy mode
for(; tmpIt!=inLayer.end(); ++tmpIt)
{
ogr::Feature dstFeature(outLayer.GetLayerDefn());
dstFeature.SetFrom( *tmpIt, TRUE );
outLayer.CreateFeature( dstFeature );
}
count++;
}
}
chrono.Stop();
otbMsgDebugMacro(<< "Writing OGR points took " << chrono.GetElapsedMilliseconds() << " ms");
this->m_InMemoryOutputs.clear();
err = outLayer.ogr().CommitTransaction();
if (err != OGRERR_NONE)
{
itkExceptionMacro(<< "Unable to commit transaction for OGR layer " << outLayer.ogr().GetName() << ".");
}
}
template <class TInputImage, class TMaskImage>
......
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