From 9b8b1b8486aff45bc69ce1b7fa289b766be2ecf9 Mon Sep 17 00:00:00 2001 From: Arnaud Jaen <arnaud.jaen@c-s.fr> Date: Thu, 15 Mar 2012 18:19:54 +0100 Subject: [PATCH] ENH: Modify ConcatenateVectorDataFilter to avoid scanning the largest vectorData (shallow copy) --- .../otbConcatenateVectorDataFilter.h | 3 +- .../otbConcatenateVectorDataFilter.txx | 89 ++++++++++++++----- .../otbPersistentImageToVectorDataFilter.h | 12 +++ .../otbPersistentImageToVectorDataFilter.txx | 5 +- 4 files changed, 86 insertions(+), 23 deletions(-) diff --git a/Code/BasicFilters/otbConcatenateVectorDataFilter.h b/Code/BasicFilters/otbConcatenateVectorDataFilter.h index 23a836e1f4..1db5d5d03b 100644 --- a/Code/BasicFilters/otbConcatenateVectorDataFilter.h +++ b/Code/BasicFilters/otbConcatenateVectorDataFilter.h @@ -34,6 +34,7 @@ namespace otb * Note that the input vectordatas must have the same node type, * this is due that vectordata creation does not support multiple geomtries * in a single vectordata. + * Warning : this filter does not create a deep copy of each node. * */ template <class TVectorData> @@ -82,7 +83,7 @@ protected: void GenerateData(void); /** Recursive method to visit efficiently the vectordata*/ - void ProcessNode(TreeNodeType * source); + void ProcessNode(TreeNodeType * source, DataNodeType * outputDocument); private: ConcatenateVectorDataFilter(const Self &); //purposely not implemented diff --git a/Code/BasicFilters/otbConcatenateVectorDataFilter.txx b/Code/BasicFilters/otbConcatenateVectorDataFilter.txx index 7511fbf10a..8464c2aaec 100644 --- a/Code/BasicFilters/otbConcatenateVectorDataFilter.txx +++ b/Code/BasicFilters/otbConcatenateVectorDataFilter.txx @@ -21,6 +21,7 @@ #include "otbConcatenateVectorDataFilter.h" #include "otbMath.h" +#include "itkTimeProbe.h" namespace otb { @@ -73,6 +74,9 @@ void ConcatenateVectorDataFilter<TVectorData> ::GenerateData() { + itk::TimeProbe tileChrono; + tileChrono.Start(); + // TODO : no checking is done on the inputs, do checking to avoid // TODO : Check if they are in the same coordinate system (tricky) @@ -82,32 +86,75 @@ ConcatenateVectorDataFilter<TVectorData> //this->GetOutput()->SetMetaDataDictionary(this->GetInput(0)->GetMetaDataDictionary()); // Prepare the output - typename DataNodeType::Pointer outputRoot = this->GetOutput()->GetDataTree()->GetRoot()->Get(); + //typename DataNodeType::Pointer outputRoot = this->GetOutput()->GetDataTree()->GetRoot()->Get(); + + // Retrieve the larger input + //itk::TimeProbe maxChrono; + //maxChrono.Start(); + /*unsigned int maxIdx = 0; + int max = 0; + for(unsigned int idx = 0; idx < this->GetNumberOfInputs(); ++idx) + { + //std::cout<<"nb feature input "<<this->GetInput(idx)->Size()<<std::endl; + if (this->GetInput(idx)->Size() > max) + { + max = this->GetInput(idx)->Size(); + maxIdx = idx; + } + } + maxChrono.Stop(); + std::cout<< "Max took " << maxChrono.GetTotal() << " sec"<<std::endl; + */ + + //std::cout<<"max index "<<maxIdx<<std::endl; + typename DataTreeType::Pointer outputTree = this->GetOutput()->GetDataTree(); + typename TreeNodeType::Pointer inputRoot = const_cast<TreeNodeType *>(this->GetInput(0)->GetDataTree()->GetRoot()); + + + outputTree->SetRoot(inputRoot); + + + typename DataNodeType::Pointer outputDocument = this->GetOutput()->GetDataTree()->GetRoot()->GetChild(0)->Get(); + + //std::cout<<"node type (document ??) "<< outputDocument->GetNodeType() <<std::endl; // Adding the layer to the data tree - this->GetOutput()->GetDataTree()->Add(m_Document, outputRoot); - this->GetOutput()->GetDataTree()->Add(m_Folder, m_Document); +// this->GetOutput()->GetDataTree()->Add(m_Document, outputRoot); +// this->GetOutput()->GetDataTree()->Add(m_Folder, m_Document); // Retrieve all the inputs - for(unsigned int idx = 0; idx < this->GetNumberOfInputs(); ++idx) + for(unsigned int idx = 1; idx < this->GetNumberOfInputs(); ++idx) { - // Add the current vectordata - TreeNodeType * - inputRoot = const_cast<TreeNodeType *>(this->GetInput(idx)->GetDataTree()->GetRoot()); - // - ProcessNode(inputRoot); + //std::cout<<"index "<<idx<<std::endl; + // Add the current vectordata + TreeNodeType * + inputRoot = const_cast<TreeNodeType *>(this->GetInput(idx)->GetDataTree()->GetRoot()); + // + + itk::TimeProbe processNodeChrono; + processNodeChrono.Start(); + + ProcessNode(inputRoot, outputDocument); + + processNodeChrono.Stop(); + std::cout<< "Process Node (concatenate) took " << processNodeChrono.GetTotal() << " sec"<<std::endl; + } - + //std::cout<<"nb feature output "<<this->GetOutput()->Size()<<std::endl; + + tileChrono.Stop(); + std::cout<< "Concatenate vector data took " << tileChrono.GetTotal() << " sec"<<std::endl; } template <class TVectorData> void ConcatenateVectorDataFilter<TVectorData> -::ProcessNode(TreeNodeType * source) +::ProcessNode(TreeNodeType * source, DataNodeType * outputDocument) { if (source == 0) return; + // Get the children list from the input node ChildrenListType children = source->GetChildrenList(); @@ -123,52 +170,52 @@ ConcatenateVectorDataFilter<TVectorData> { case ROOT: { - ProcessNode((*it)); + ProcessNode((*it), outputDocument); break; } case DOCUMENT: { - ProcessNode((*it)); + ProcessNode((*it), outputDocument); break; } case FOLDER: { - ProcessNode((*it)); + ProcessNode((*it), outputDocument); break; } case FEATURE_POINT: { - this->GetOutput()->GetDataTree()->Add(dataNode, m_Document); + this->GetOutput()->GetDataTree()->Add(dataNode, outputDocument); break; } case FEATURE_LINE: { - this->GetOutput()->GetDataTree()->Add(dataNode, m_Document); + this->GetOutput()->GetDataTree()->Add(dataNode, outputDocument); break; } case FEATURE_POLYGON: { - this->GetOutput()->GetDataTree()->Add(dataNode, m_Document); + this->GetOutput()->GetDataTree()->Add(dataNode, outputDocument); break; } case FEATURE_MULTIPOINT: { - ProcessNode((*it)); + ProcessNode((*it), outputDocument); break; } case FEATURE_MULTILINE: { - ProcessNode((*it)); + ProcessNode((*it), outputDocument); break; } case FEATURE_MULTIPOLYGON: { - ProcessNode((*it)); + ProcessNode((*it), outputDocument); break; } case FEATURE_COLLECTION: { - ProcessNode((*it)); + ProcessNode((*it), outputDocument); break; } } diff --git a/Code/Common/otbPersistentImageToVectorDataFilter.h b/Code/Common/otbPersistentImageToVectorDataFilter.h index af44060499..2e70071978 100644 --- a/Code/Common/otbPersistentImageToVectorDataFilter.h +++ b/Code/Common/otbPersistentImageToVectorDataFilter.h @@ -25,6 +25,8 @@ #include "itkExtractImageFilter.h" #include "otbConcatenateVectorDataFilter.h" +#include "otbOGRVectorDataIO.h" +#include "itkMacro.h" namespace otb { @@ -72,6 +74,9 @@ public: typedef otb::ConcatenateVectorDataFilter<OutputVectorDataType> ConcatenateVectorDataFilterType; typedef typename ConcatenateVectorDataFilterType::Pointer ConcatenateVectorDataFilterPointerType; + + typedef otb::OGRVectorDataIO OGRVectorDataIOType; + typedef typename OGRVectorDataIOType::Pointer OGRVectorDataIOPointerType; /** Smart Pointer type to a DataObject. */ typedef itk::DataObject::Pointer DataObjectPointer; @@ -83,6 +88,10 @@ public: virtual void Reset(void); virtual void Synthetize(void); + + /** Specify the name of the output shapefile to write. */ + itkSetStringMacro(FileName); + itkGetStringMacro(FileName); protected: PersistentImageToVectorDataFilter(); @@ -101,6 +110,9 @@ private: void operator =(const Self&); //purposely not implemented virtual OutputVectorDataPointerType ProcessTile() = 0; + + OGRVectorDataIOPointerType m_VectorDataIO; + std::string m_FileName; }; // end of class } // end namespace otb diff --git a/Code/Common/otbPersistentImageToVectorDataFilter.txx b/Code/Common/otbPersistentImageToVectorDataFilter.txx index 4c5b257c1e..1bfcd993fa 100644 --- a/Code/Common/otbPersistentImageToVectorDataFilter.txx +++ b/Code/Common/otbPersistentImageToVectorDataFilter.txx @@ -32,6 +32,8 @@ PersistentImageToVectorDataFilter<TImage, TOutputVectorData> { m_ExtractFilter = ExtractImageFilterType::New(); m_OutputVectorData = OutputVectorDataType::New(); + + m_VectorDataIO = OGRVectorDataIOType::New(); } template<class TImage, class TOutputVectorData> @@ -92,9 +94,10 @@ PersistentImageToVectorDataFilter<TImage, TOutputVectorData> // merge the result into the output vector data object OutputVectorDataPointerType output = GetOutputVectorData(); + ConcatenateVectorDataFilterPointerType concatenate = ConcatenateVectorDataFilterType::New(); - concatenate->AddInput(currentTileVD); concatenate->AddInput(output); + concatenate->AddInput(currentTileVD); concatenate->Update(); concatenate->GetOutput()->SetMetaDataDictionary(currentTileVD->GetMetaDataDictionary()); -- GitLab