diff --git a/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.h b/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.h index 77388ff308006d5157bbd1cbb1c460132c78d674..8393766bcb81489c5e2582e2b1a38bb8912a4251 100644 --- a/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.h +++ b/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.h @@ -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 diff --git a/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.txx b/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.txx index e2d8a40810ea938c874108af958fadd66e9ebb4e..cc70bcbb953570890938f3aa1f72993ac487e19b 100644 --- a/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.txx +++ b/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.txx @@ -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> diff --git a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.h b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.h index 8e80fb9e0e77c81e28834d36b1921b09768266a9..bb3b0ac40623ccd7766562f13755ad3e18cae45d 100644 --- a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.h +++ b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.h @@ -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); diff --git a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx index f10ace96a9ba43e0194a191e2bcd57320fed310a..2973a7a8a3a2e251cdef0ffcf55f034eb6b217aa 100644 --- a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx +++ b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx @@ -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>