diff --git a/Modules/Learning/Sampling/include/otbImageSampleExtractorFilter.h b/Modules/Learning/Sampling/include/otbImageSampleExtractorFilter.h index b561c7896e1f1b2690843453d33ced91d2424963..e0cc84306641eae3f726dd8beaf5c47ed6e575af 100644 --- a/Modules/Learning/Sampling/include/otbImageSampleExtractorFilter.h +++ b/Modules/Learning/Sampling/include/otbImageSampleExtractorFilter.h @@ -69,8 +69,8 @@ public: /** Get the output samples OGR container */ ogr::DataSource* GetOutputSamples(); - - virtual void Synthetize(void); + + virtual void Synthetize(void){} /** Reset method called before starting the streaming*/ virtual void Reset(void); @@ -95,7 +95,7 @@ protected: virtual void GenerateInputRequestedRegion(); /** process only points */ - virtual void ThreadedGenerateData(const RegionType&, itk::ThreadIdType threadid); + virtual void ThreadedGenerateVectorData(const ogr::Layer& layerForThread, itk::ThreadIdType threadid); private: PersistentImageSampleExtractorFilter(const Self &); //purposely not implemented diff --git a/Modules/Learning/Sampling/include/otbImageSampleExtractorFilter.txx b/Modules/Learning/Sampling/include/otbImageSampleExtractorFilter.txx index d26890ebf63e4a1f65e4ef8e408f2a4734a62f62..341098e45452c3b53b78001c4090de562e73fa78 100644 --- a/Modules/Learning/Sampling/include/otbImageSampleExtractorFilter.txx +++ b/Modules/Learning/Sampling/include/otbImageSampleExtractorFilter.txx @@ -55,15 +55,6 @@ PersistentImageSampleExtractorFilter<TInputImage> return static_cast<ogr::DataSource *>(this->itk::ProcessObject::GetOutput(1)); } -template<class TInputImage> -void -PersistentImageSampleExtractorFilter<TInputImage> -::Synthetize(void) -{ - // clear temporary outputs - this->m_InMemoryOutputs.clear(); -} - template<class TInputImage> void PersistentImageSampleExtractorFilter<TInputImage> @@ -165,20 +156,15 @@ PersistentImageSampleExtractorFilter<TInputImage> template<class TInputImage> void PersistentImageSampleExtractorFilter<TInputImage> -::ThreadedGenerateData(const RegionType&, itk::ThreadIdType threadid) +::ThreadedGenerateVectorData(const ogr::Layer& layerForThread, itk::ThreadIdType threadid) { // Retrieve inputs TInputImage* inputImage = const_cast<TInputImage*>(this->GetInput()); unsigned int nbBand = inputImage->GetNumberOfComponentsPerPixel(); - ogr::Layer layer = this->m_InMemoryInputs[threadid]->GetLayerChecked(0); - if (! layer) - { - return; - } - ogr::Layer outputLayer = this->m_InMemoryOutputs[threadid][0]->GetLayerChecked(0); + ogr::Layer outputLayer = this->GetInMemoryOutput(threadid); - itk::ProgressReporter progress( this, threadid, layer.GetFeatureCount(true) ); + itk::ProgressReporter progress( this, threadid, layerForThread.GetFeatureCount(true) ); // Loop across the features in the layer (filtered by requested region in BeforeTGD already) OGRGeometry *geom; @@ -186,8 +172,8 @@ PersistentImageSampleExtractorFilter<TInputImage> IndexType imgIndex; PixelType imgPixel; double imgComp; - ogr::Layer::const_iterator featIt = layer.begin(); - for(; featIt!=layer.end(); ++featIt) + ogr::Layer::const_iterator featIt = layerForThread.begin(); + for(; featIt!=layerForThread.end(); ++featIt) { geom = featIt->ogr().GetGeometryRef(); switch (geom->getGeometryType()) diff --git a/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.h b/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.h index 10e23d11b3622b6b5a467f0833d4e9d41440690e..7e7b9b92db373bb732e6f988413adddd032c8853 100644 --- a/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.h +++ b/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.h @@ -85,8 +85,7 @@ public: /** Runtime information support. */ itkTypeMacro(PersistentOGRDataToSamplePositionFilter, PersistentSamplingFilterBase); - /** Synthetize the persistent filter*/ - virtual void Synthetize(void); + virtual void Synthetize(void){} /** Reset method called before starting the streaming*/ virtual void Reset(void); @@ -135,7 +134,7 @@ protected: /** Method to split the input OGRDataSource * according to the class partition */ - virtual void DispatchInputVectors(ogr::Layer &inLayer, std::vector<ogr::Layer> &tmpLayers); + virtual void DispatchInputVectors(void); private: PersistentOGRDataToSamplePositionFilter(const Self &); //purposely not implemented diff --git a/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.txx b/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.txx index 41eb0172de479cdcc0f456d9f4b42906c5a8dd99..d2e6847e1f64bf95a19d6ba9c12d1023632c4fa2 100644 --- a/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.txx +++ b/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.txx @@ -33,15 +33,6 @@ PersistentOGRDataToSamplePositionFilter<TInputImage,TMaskImage,TSampler> m_OriginFieldName = std::string("originfid"); } -template<class TInputImage, class TMaskImage, class TSampler> -void -PersistentOGRDataToSamplePositionFilter<TInputImage,TMaskImage,TSampler> -::Synthetize(void) -{ - // clear temporary outputs - this->m_InMemoryOutputs.clear(); -} - template<class TInputImage, class TMaskImage, class TSampler> void PersistentOGRDataToSamplePositionFilter<TInputImage,TMaskImage,TSampler> @@ -185,7 +176,7 @@ PersistentOGRDataToSamplePositionFilter<TInputImage,TMaskImage,TSampler> ogrTmpPoint.setX(imgPoint[0]); ogrTmpPoint.setY(imgPoint[1]); - ogr::Layer outputLayer = this->m_InMemoryOutputs[threadid][i]->GetLayerChecked(0); + ogr::Layer outputLayer = this->GetInMemoryOutput(threadid,i); ogr::Feature feat(outputLayer.GetLayerDefn()); feat.SetFrom(feature); feat[this->GetOriginFieldName()].SetValue(static_cast<int>(feature.GetFID())); @@ -199,8 +190,43 @@ PersistentOGRDataToSamplePositionFilter<TInputImage,TMaskImage,TSampler> template<class TInputImage, class TMaskImage, class TSampler> void PersistentOGRDataToSamplePositionFilter<TInputImage,TMaskImage,TSampler> -::DispatchInputVectors(ogr::Layer &inLayer, std::vector<ogr::Layer> &tmpLayers) +::DispatchInputVectors() { + TInputImage* outputImage = this->GetOutput(); + ogr::DataSource* vectors = const_cast<ogr::DataSource*>(this->GetOGRData()); + ogr::Layer inLayer = vectors->GetLayer(this->GetLayerIndex()); + + const RegionType& requestedRegion = outputImage->GetRequestedRegion(); + itk::ContinuousIndex<double> startIndex(requestedRegion.GetIndex()); + itk::ContinuousIndex<double> endIndex(requestedRegion.GetUpperIndex()); + startIndex[0] += -0.5; + startIndex[1] += -0.5; + endIndex[0] += 0.5; + endIndex[1] += 0.5; + itk::Point<double, 2> startPoint; + itk::Point<double, 2> endPoint; + outputImage->TransformContinuousIndexToPhysicalPoint(startIndex, startPoint); + outputImage->TransformContinuousIndexToPhysicalPoint(endIndex, endPoint); + + // create geometric extent + OGRPolygon tmpPolygon; + OGRLinearRing ring; + ring.addPoint(startPoint[0],startPoint[1],0.0); + ring.addPoint(startPoint[0],endPoint[1] ,0.0); + ring.addPoint(endPoint[0] ,endPoint[1] ,0.0); + ring.addPoint(endPoint[0] ,startPoint[1],0.0); + ring.addPoint(startPoint[0],startPoint[1],0.0); + tmpPolygon.addRing(&ring); + + inLayer.SetSpatialFilter(&tmpPolygon); + + unsigned int numberOfThreads = this->GetNumberOfThreads(); + std::vector<ogr::Layer> tmpLayers; + for (unsigned int i=0 ; i<numberOfThreads ; i++) + { + tmpLayers.push_back(this->GetInMemoryInput(i)); + } + OGRFeatureDefn &layerDefn = inLayer.GetLayerDefn(); ogr::Layer::const_iterator featIt = inLayer.begin(); std::string className; @@ -212,6 +238,8 @@ PersistentOGRDataToSamplePositionFilter<TInputImage,TMaskImage,TSampler> className = featIt->ogr().GetFieldAsString(this->GetFieldIndex()); tmpLayers[m_ClassPartition[className]].CreateFeature( dstFeature ); } + + inLayer.SetSpatialFilter(ITK_NULLPTR); } template<class TInputImage, class TMaskImage, class TSampler> diff --git a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.h b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.h index 498dfe5383693cdcac7fe22ab7673bedb9970330..37d40fa88eb2eec057c274655bb7f1480515df55 100644 --- a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.h +++ b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.h @@ -104,15 +104,14 @@ protected: * the requested region for the mask */ virtual void GenerateInputRequestedRegion(); - /** Prepare temporary input and output OGR data sources */ - virtual void BeforeThreadedGenerateData(void); + /** Generate data should thread over */ + virtual void GenerateData(void); - /** Gather data from multiple threads and - * write to output OGRDataSource (if any) */ - virtual void AfterThreadedGenerateData(void); + /** Allocate in-memory layers for input and outputs */ + virtual void AllocateOutputs(void); /** Start of main processing loop */ - virtual void ThreadedGenerateData(const RegionType&, itk::ThreadIdType threadid); + virtual void ThreadedGenerateVectorData(const ogr::Layer& layerForThread, itk::ThreadIdType threadid); /** Process a geometry, recursive method when the geometry is a collection */ void ExploreGeometry(const ogr::Feature& feature, @@ -155,28 +154,17 @@ protected: /** Get the region bounding a set of features */ RegionType FeatureBoundingRegion(const TInputImage* image, otb::ogr::Layer::const_iterator& featIt) const; - /** Prepares in-memory layers for each thread, - * then calls DispatchInputVectors() for the actual dispatch */ - virtual void PrepareInputVectors(); - /** Method to split the input OGRDataSource between several containers * for each thread. Default is to put the same number of features for * each thread.*/ - virtual void DispatchInputVectors(ogr::Layer &inLayer, std::vector<ogr::Layer> &tmpLayers); + virtual void DispatchInputVectors(void); - /** Prepare output feature containers for each thread and each output - * OGRDataSource*/ - virtual void PrepareOutputVectors(); + /** Gather the content of in-memory output layer into the filter outputs */ + virtual void GatherOutputVectors(void); /** Utility method to add new fields on an output layer */ virtual void InitializeOutputDataSource(ogr::DataSource* inputDS, ogr::DataSource* outputDS); - /** In-memory containers storing input geometries for each thread*/ - std::vector<OGRDataPointer> m_InMemoryInputs; - - /** In-memory containers storing position during iteration loop*/ - std::vector<std::vector<OGRDataPointer> > m_InMemoryOutputs; - typedef struct { std::string Name; OGRFieldType Type; @@ -196,6 +184,21 @@ protected: /** Get a reference over the additional fields */ const std::vector<SimpleFieldDefn>& GetAdditionalFields(); + /** Callback function to launch VectorThreadedGenerateData in each thread */ + static ITK_THREAD_RETURN_TYPE VectorThreaderCallback(void *arg); + + /** basically the same struct as itk::ImageSource::ThreadStruct */ + struct VectorThreadStruct + { + Pointer Filter; + }; + + /** Give access to in-memory input layers */ + ogr::Layer GetInMemoryInput(unsigned int threadId); + + /** Give access to in-memory output layers */ + ogr::Layer GetInMemoryOutput(unsigned int threadId, unsigned int index=0); + private: PersistentSamplingFilterBase(const Self &); //purposely not implemented void operator =(const Self&); //purposely not implemented @@ -218,6 +221,12 @@ private: /** Additional field definitions to add in output data sources */ std::vector<SimpleFieldDefn> m_AdditionalFields; + /** In-memory containers storing input geometries for each thread*/ + std::vector<OGRDataPointer> m_InMemoryInputs; + + /** In-memory containers storing position during iteration loop*/ + std::vector<std::vector<OGRDataPointer> > m_InMemoryOutputs; + }; } // End namespace otb diff --git a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx index d5b04ef547dd71da99a333cc32295259453b9075..e76567c4e844189951dd4d416688baa7e00cc474 100644 --- a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx +++ b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx @@ -158,34 +158,119 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage> } } - template <class TInputImage, class TMaskImage> void PersistentSamplingFilterBase<TInputImage,TMaskImage> -::BeforeThreadedGenerateData(void) +::GenerateData(void) { - this->PrepareInputVectors(); + this->AllocateOutputs(); + this->BeforeThreadedGenerateData(); + + // Split the data into in-memory layers + this->DispatchInputVectors(); + + // struct to store filter pointer + VectorThreadStruct str; + str.Filter = this; + + // Get the output pointer + //const InputImageType *outputPtr = this->GetOutput(); + + this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfThreads() ); + this->GetMultiThreader()->SetSingleMethod(this->VectorThreaderCallback, &str); + + // multithread the execution + this->GetMultiThreader()->SingleMethodExecute(); - this->PrepareOutputVectors(); + // gather the data from in-memory output layers + this->GatherOutputVectors(); + + this->AfterThreadedGenerateData(); } template <class TInputImage, class TMaskImage> void PersistentSamplingFilterBase<TInputImage,TMaskImage> -::AfterThreadedGenerateData(void) +::AllocateOutputs(void) { - // clean temporary inputs - this->m_InMemoryInputs.clear(); + Superclass::AllocateOutputs(); + + ogr::DataSource* vectors = const_cast<ogr::DataSource*>(this->GetOGRData()); + ogr::Layer inLayer = vectors->GetLayer(m_LayerIndex); unsigned int numberOfThreads = this->GetNumberOfThreads(); - - unsigned int actualNumberOfThreads = numberOfThreads; - - if(numberOfThreads > this->GetOutput()->GetRequestedRegion().GetSize()[1]) + + // Prepare temporary input + this->m_InMemoryInputs.clear(); + this->m_InMemoryInputs.reserve(numberOfThreads); + std::string tmpLayerName("thread"); + OGRSpatialReference * oSRS = ITK_NULLPTR; + if (inLayer.GetSpatialRef()) { - actualNumberOfThreads = this->GetOutput()->GetRequestedRegion().GetSize()[1]; + oSRS = inLayer.GetSpatialRef()->Clone(); + } + OGRFeatureDefn &layerDefn = inLayer.GetLayerDefn(); + //std::vector<ogr::Layer> tmpLayers; + for (unsigned int i=0 ; i < numberOfThreads ; i++) + { + ogr::DataSource::Pointer tmpOgrDS = ogr::DataSource::New(); + ogr::Layer tmpLayer = tmpOgrDS->CreateLayer( + tmpLayerName, + oSRS, + inLayer.GetGeomType()); + // add field definitions + for (int k=0 ; k < layerDefn.GetFieldCount() ; k++) + { + OGRFieldDefn originDefn(layerDefn.GetFieldDefn(k)); + ogr::FieldDefn fieldDefn(originDefn); + tmpLayer.CreateField(fieldDefn); + } + this->m_InMemoryInputs.push_back(tmpOgrDS); } + // Prepare in-memory outputs + this->m_InMemoryOutputs.clear(); + this->m_InMemoryOutputs.reserve(numberOfThreads); + tmpLayerName = std::string("threadOut"); + for (unsigned int i=0 ; i < numberOfThreads ; i++) + { + std::vector<OGRDataPointer> tmpContainer; + // iterate over outputs, only process ogr::DataSource + for (unsigned int k=0 ; k < this->GetNumberOfOutputs() ; k++) + { + ogr::DataSource* realOutput = dynamic_cast<ogr::DataSource *>( + this->itk::ProcessObject::GetOutput(k)); + if (realOutput) + { + ogr::Layer realLayer = realOutput->GetLayersCount() == 1 + ? realOutput->GetLayer(0) + : realOutput->GetLayer(m_OutLayerName); + OGRFeatureDefn &outLayerDefn = realLayer.GetLayerDefn(); + ogr::DataSource::Pointer tmpOutput = ogr::DataSource::New(); + ogr::Layer tmpLayer = tmpOutput->CreateLayer( + tmpLayerName, oSRS, realLayer.GetGeomType()); + // add field definitions + for (int f=0 ; f < outLayerDefn.GetFieldCount() ; f++) + { + OGRFieldDefn originDefn(outLayerDefn.GetFieldDefn(f)); + tmpLayer.CreateField(originDefn); + } + tmpContainer.push_back(tmpOutput); + } + } + this->m_InMemoryOutputs.push_back(tmpContainer); + } +} + +template <class TInputImage, class TMaskImage> +void +PersistentSamplingFilterBase<TInputImage,TMaskImage> +::GatherOutputVectors(void) +{ + // 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(); @@ -208,7 +293,7 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage> itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << "."); } - for (unsigned int thread=0 ; thread < actualNumberOfThreads ; thread++) + for (unsigned int thread=0 ; thread < numberOfThreads ; thread++) { ogr::Layer inLayer = this->m_InMemoryOutputs[thread][count]->GetLayerChecked(0); if (!inLayer) @@ -248,29 +333,24 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage> } chrono.Stop(); otbMsgDebugMacro(<< "write ogr points took " << chrono.GetTotal() << " sec"); + this->m_InMemoryOutputs.clear(); } template <class TInputImage, class TMaskImage> void PersistentSamplingFilterBase<TInputImage,TMaskImage> -::ThreadedGenerateData(const RegionType&, itk::ThreadIdType threadid) +::ThreadedGenerateVectorData(const ogr::Layer& layerForThread, itk::ThreadIdType threadid) { // Retrieve inputs TInputImage* inputImage = const_cast<TInputImage*>(this->GetInput()); TInputImage* outputImage = this->GetOutput(); RegionType requestedRegion = outputImage->GetRequestedRegion(); - ogr::Layer layer = this->m_InMemoryInputs.at(threadid)->GetLayerChecked(0); - if (! layer) - { - return; - } - - itk::ProgressReporter progress( this, threadid, layer.GetFeatureCount(true) ); + itk::ProgressReporter progress( this, threadid, layerForThread.GetFeatureCount(true) ); // Loop across the features in the layer (filtered by requested region in BeforeTGD already) - ogr::Layer::const_iterator featIt = layer.begin(); - for(; featIt!=layer.end(); ++featIt) + ogr::Layer::const_iterator featIt = layerForThread.begin(); + for(; featIt!=layerForThread.end(); ++featIt) { // Compute the intersection of thread region and polygon bounding region, called "considered region" // This need not be done in ThreadedGenerateData and could be pre-processed and cached before filter execution if needed @@ -603,7 +683,7 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage> template<class TInputImage, class TMaskImage> void PersistentSamplingFilterBase<TInputImage,TMaskImage> -::PrepareInputVectors() +::DispatchInputVectors() { TInputImage* outputImage = this->GetOutput(); ogr::DataSource* vectors = const_cast<ogr::DataSource*>(this->GetOGRData()); @@ -634,52 +714,13 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage> inLayer.SetSpatialFilter(&tmpPolygon); unsigned int numberOfThreads = this->GetNumberOfThreads(); - - unsigned int actualNumberOfThreads = numberOfThreads; - - if(numberOfThreads > this->GetOutput()->GetRequestedRegion().GetSize()[1]) - { - actualNumberOfThreads = this->GetOutput()->GetRequestedRegion().GetSize()[1]; - } - - // prepare temporary input : split input features between available threads - this->m_InMemoryInputs.clear(); - std::string tmpLayerName("thread"); - OGRSpatialReference * oSRS = ITK_NULLPTR; - if (inLayer.GetSpatialRef()) - { - oSRS = inLayer.GetSpatialRef()->Clone(); - } - OGRFeatureDefn &layerDefn = inLayer.GetLayerDefn(); std::vector<ogr::Layer> tmpLayers; - for (unsigned int i=0 ; i < actualNumberOfThreads ; i++) + tmpLayers.reserve(numberOfThreads); + for (unsigned int i=0 ; i<numberOfThreads ; i++) { - ogr::DataSource::Pointer tmpOgrDS = ogr::DataSource::New(); - ogr::Layer tmpLayer = tmpOgrDS->CreateLayer( - tmpLayerName, - oSRS, - inLayer.GetGeomType()); - // add field definitions - for (int k=0 ; k < layerDefn.GetFieldCount() ; k++) - { - OGRFieldDefn originDefn(layerDefn.GetFieldDefn(k)); - ogr::FieldDefn fieldDefn(originDefn); - tmpLayer.CreateField(fieldDefn); - } - this->m_InMemoryInputs.push_back(tmpOgrDS); - tmpLayers.push_back(tmpLayer); + tmpLayers.push_back(this->GetInMemoryInput(i)); } - - this->DispatchInputVectors(inLayer,tmpLayers); - - inLayer.SetSpatialFilter(ITK_NULLPTR); -} - -template<class TInputImage, class TMaskImage> -void -PersistentSamplingFilterBase<TInputImage,TMaskImage> -::DispatchInputVectors(ogr::Layer &inLayer, std::vector<ogr::Layer> &tmpLayers) -{ + OGRFeatureDefn &layerDefn = inLayer.GetLayerDefn(); ogr::Layer::const_iterator featIt = inLayer.begin(); unsigned int counter=0; @@ -693,58 +734,8 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage> if (counter >= tmpLayers.size()) counter = 0; } -} -template<class TInputImage, class TMaskImage> -void -PersistentSamplingFilterBase<TInputImage,TMaskImage> -::PrepareOutputVectors() -{ - // Prepare in-memory outputs - unsigned int numberOfThreads = this->GetNumberOfThreads(); - - unsigned int actualNumberOfThreads = numberOfThreads; - - if(numberOfThreads > this->GetOutput()->GetRequestedRegion().GetSize()[1]) - { - actualNumberOfThreads = this->GetOutput()->GetRequestedRegion().GetSize()[1]; - } - - this->m_InMemoryOutputs.clear(); - std::string tmpLayerName("threadOut"); - for (unsigned int i=0 ; i < actualNumberOfThreads ; i++) - { - std::vector<OGRDataPointer> tmpContainer; - // iterate over outputs, only process ogr::DataSource - for (unsigned int k=0 ; k < this->GetNumberOfOutputs() ; k++) - { - ogr::DataSource* realOutput = dynamic_cast<ogr::DataSource *>( - this->itk::ProcessObject::GetOutput(k)); - if (realOutput) - { - ogr::Layer realLayer = realOutput->GetLayersCount() == 1 - ? realOutput->GetLayer(0) - : realOutput->GetLayer(m_OutLayerName); - OGRSpatialReference * oSRS = ITK_NULLPTR; - if (realLayer.GetSpatialRef()) - { - oSRS = realLayer.GetSpatialRef()->Clone(); - } - OGRFeatureDefn &layerDefn = realLayer.GetLayerDefn(); - ogr::DataSource::Pointer tmpOutput = ogr::DataSource::New(); - ogr::Layer tmpLayer = tmpOutput->CreateLayer( - tmpLayerName, oSRS, realLayer.GetGeomType()); - // add field definitions - for (int f=0 ; f < layerDefn.GetFieldCount() ; f++) - { - OGRFieldDefn originDefn(layerDefn.GetFieldDefn(f)); - tmpLayer.CreateField(originDefn); - } - tmpContainer.push_back(tmpOutput); - } - } - this->m_InMemoryOutputs.push_back(tmpContainer); - } + inLayer.SetSpatialFilter(ITK_NULLPTR); } template<class TInputImage, class TMaskImage> @@ -857,6 +848,53 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage> return this->m_AdditionalFields; } +template<class TInputImage, class TMaskImage> +ITK_THREAD_RETURN_TYPE +PersistentSamplingFilterBase<TInputImage,TMaskImage> +::VectorThreaderCallback(void *arg) +{ + VectorThreadStruct *str = (VectorThreadStruct*)(((itk::MultiThreader::ThreadInfoStruct *)(arg))->UserData); + + int threadId = ((itk::MultiThreader::ThreadInfoStruct *)(arg))->ThreadID; + int threadCount = ((itk::MultiThreader::ThreadInfoStruct *)(arg))->NumberOfThreads; + + ogr::Layer layer = str->Filter->GetInMemoryInput(threadId); + + if (threadId < threadCount) + { + str->Filter->ThreadedGenerateVectorData(layer,threadId); + } + + return ITK_THREAD_RETURN_VALUE; +} + +template<class TInputImage, class TMaskImage> +ogr::Layer +PersistentSamplingFilterBase<TInputImage,TMaskImage> +::GetInMemoryInput(unsigned int threadId) +{ + if (threadId >= m_InMemoryInputs.size()) + { + itkExceptionMacro(<< "Requested in-memory input layer not available " << threadId << " (total size : "<< m_InMemoryInputs.size() <<")."); + } + return m_InMemoryInputs[threadId]->GetLayerChecked(0); +} + +template<class TInputImage, class TMaskImage> +ogr::Layer +PersistentSamplingFilterBase<TInputImage,TMaskImage> +::GetInMemoryOutput(unsigned int threadId, unsigned int index) +{ + if (threadId >= m_InMemoryOutputs.size()) + { + itkExceptionMacro(<< "Requested in-memory output layer not available " << threadId << " (total size : "<< m_InMemoryOutputs.size() <<")."); + } + if (index >= m_InMemoryOutputs[threadId].size()) + { + itkExceptionMacro(<< "Requested output dataset not available " << index << " (available : "<< m_InMemoryOutputs[threadId].size() <<")."); + } + return m_InMemoryOutputs[threadId][index]->GetLayerChecked(0); +} } // end namespace otb