diff --git a/Code/OBIA/otbLabelImageToOGRDataSourceFilter.txx b/Code/OBIA/otbLabelImageToOGRDataSourceFilter.txx index d89a0d8368700375d543bafb5bb8e6decc8c6dab..97f45930042bb45310d42d31e93ae73527a334f4 100644 --- a/Code/OBIA/otbLabelImageToOGRDataSourceFilter.txx +++ b/Code/OBIA/otbLabelImageToOGRDataSourceFilter.txx @@ -223,7 +223,7 @@ LabelImageToOGRDataSourceFilter<TInputImage> OGRSFDriver * ogrDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driverName); OGRDataSource * dataSource = ogrDriver->CreateDataSource("Shape",NULL); - OGRLayer * outputLayer = dataSource->CreateLayer("toto",NULL,wkbMultiPolygon,NULL); + OGRLayer * outputLayer = dataSource->CreateLayer("layer",NULL,wkbMultiPolygon,NULL); OGRFieldDefn field(m_FieldName.c_str(),OFTInteger); outputLayer->CreateField(&field, true); @@ -243,7 +243,6 @@ LabelImageToOGRDataSourceFilter<TInputImage> //Clear memory GDALClose(dataset); - } diff --git a/Code/OBIA/otbPersistentImageToOGRDataFilter.h b/Code/OBIA/otbPersistentImageToOGRDataFilter.h index 1662b705ffbd4c9ee77be343c2e7e8ae15079e00..0f6ca15358424afb8a75c4b0488aae2179fd9594 100644 --- a/Code/OBIA/otbPersistentImageToOGRDataFilter.h +++ b/Code/OBIA/otbPersistentImageToOGRDataFilter.h @@ -82,8 +82,11 @@ public: virtual void Initialize(void); /** Specify the name of the output shapefile to write. */ - void SetFileName(const std::string & filename); + itkSetStringMacro(FileName); itkGetStringMacro(FileName); + + itkSetMacro(FieldName, std::string); + itkGetMacro(FieldName, std::string); protected: PersistentImageToOGRDataFilter(); @@ -100,6 +103,9 @@ private: virtual OGRDataSourceObjectPointerType ProcessTile() = 0; + std::string GetOGRDriverName(std::string name) const; + + std::string m_FieldName; std::string m_FileName; unsigned int m_TileNum; OGRDataSource * m_DataSource; diff --git a/Code/OBIA/otbPersistentImageToOGRDataFilter.txx b/Code/OBIA/otbPersistentImageToOGRDataFilter.txx index 813891d66c43678bfe8fd678f1a492c06b610f94..ad2061f9ade278322be2fd4fdbc1a497274f4ad1 100644 --- a/Code/OBIA/otbPersistentImageToOGRDataFilter.txx +++ b/Code/OBIA/otbPersistentImageToOGRDataFilter.txx @@ -23,6 +23,8 @@ #include "otbPersistentImageToOGRDataFilter.h" #include "ogrsf_frmts.h" +#include "itksys/SystemTools.hxx" +#include "otbSystem.h" namespace otb { @@ -32,7 +34,7 @@ namespace otb template<class TImage> PersistentImageToOGRDataFilter<TImage> -::PersistentImageToOGRDataFilter() : m_FileName(""), m_TileNum(0) +::PersistentImageToOGRDataFilter() : m_FieldName("DN"), m_FileName(""), m_TileNum(0) { // OGR factory registration OGRRegisterAll(); @@ -48,6 +50,39 @@ PersistentImageToOGRDataFilter<TImage> } } +template<class TImage> +std::string +PersistentImageToOGRDataFilter<TImage> +::GetOGRDriverName(std::string name) const +{ + std::string extension; + std::string driverOGR; + + std::string upperName; + upperName = name; + std::transform(name.begin(), name.end(), upperName.begin(), (int (*)(int))toupper); + + //Test of PostGIS connection string + if (upperName.substr(0, 3) == "PG:") + { + driverOGR = "PostgreSQL"; + } + else + { + extension = System::GetExtension(upperName); + if (extension == "SHP") driverOGR = "ESRI Shapefile"; + else if ((extension == "TAB")) driverOGR = "MapInfo File"; + else if (extension == "GML") driverOGR = "GML"; + else if (extension == "GPX") driverOGR = "GPX"; + else if (extension == "SQLITE") driverOGR = "SQLite"; +// else if (extension=="KML") +// driverOGR="KML"; + else driverOGR = "NOT-FOUND"; + } + return driverOGR; +} + + template<class TImage> void PersistentImageToOGRDataFilter<TImage> @@ -90,26 +125,24 @@ PersistentImageToOGRDataFilter<TImage> oSRS = static_cast<OGRSpatialReference *>(OSRNewSpatialReference(projectionRefWkt.c_str())); } OGRSFDriver * ogrDriver; - //OGRSFDriverRegistrar::Open(this->m_FileName.c_str(), FALSE, &ogrDriver); - ogrDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName("ESRI Shapefile"); - m_DataSource = ogrDriver->CreateDataSource(this->m_FileName.c_str(), NULL); - m_DataSource->CreateLayer("titi", oSRS ,wkbMultiPolygon, NULL); - - OGRFieldDefn field("DN",OFTInteger); - m_DataSource->GetLayer(0)->CreateField(&field, true); - - std::cout<<"bon ok "<<std::endl; -} + std::string driverName = this->GetOGRDriverName(this->m_FileName).data(); + if(driverName != "NOT-FOUND") + { + ogrDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driverName.c_str()); + m_DataSource = ogrDriver->CreateDataSource(this->m_FileName.c_str(), NULL); + m_DataSource->CreateLayer("layer", oSRS ,wkbMultiPolygon, NULL); + + OGRFieldDefn field(m_FieldName.c_str(),OFTInteger); + m_DataSource->GetLayer(0)->CreateField(&field, true); + } + else + { + itkExceptionMacro(<< "No OGR driver found to write file " << this->m_FileName); + } -template<class TImage> -void -PersistentImageToOGRDataFilter<TImage> -::SetFileName(const std::string & filename) -{ - m_FileName = filename; - this->Initialize(); } + template<class TImage> void PersistentImageToOGRDataFilter<TImage> @@ -118,25 +151,14 @@ PersistentImageToOGRDataFilter<TImage> // call the processing function for this tile OGRDataSourceObjectPointerType currentTileVD = this->ProcessTile(); OGRLayer * poSrcLayer = currentTileVD->Get()->GetDataSource()->GetLayer(0); - - std::ostringstream stream; - stream << m_TileNum; - - //m_DataSource->CopyLayer(tileLayer,stream.str().c_str(),NULL); - //create the layer corresponding to the tile processed ! + OGRLayer * poDstLayer; poDstLayer = m_DataSource->GetLayer(0); - - //poDstLayer = m_DataSource->CreateLayer(stream.str().c_str(),poSrcLayer->GetSpatialRef() ,poSrcLayer->GetGeomType(), NULL); - //Copy features + //Copy features in the output layer poSrcLayer->ResetReading(); - OGRFieldDefn * layerDefn = poSrcLayer->GetLayerDefn()->GetFieldDefn(0); - /*std::cout<<"ouaip "<< layerDefn->GetNameRef() <<std::endl; - poDstLayer->CreateField(layerDefn, true); - std::cout<<"create field ok"<<std::endl;*/ unsigned int nbFeatures = poSrcLayer->GetFeatureCount(true); - //std::cout<<"nb Features : "<<nbFeatures <<std::endl; +// std::cout<< "pppppp"<<std::endl; unsigned int i = 0; OGRFeature *poFeature; while (i<nbFeatures) @@ -149,16 +171,15 @@ PersistentImageToOGRDataFilter<TImage> poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() ); poDstFeature->SetFrom( poFeature, TRUE ); - poDstLayer->CreateFeature( poDstFeature ); + //free memory OGRFeature::DestroyFeature( poDstFeature ); OGRFeature::DestroyFeature( poFeature ); i++; } - // OGRDataSource::DestroyDataSource(currentTileVD->Get()->GetDataSource()); diff --git a/Code/OBIA/otbStreamingVectorizedSegmentationOGR.h b/Code/OBIA/otbStreamingVectorizedSegmentationOGR.h index 5dc387206209ec85db7a9f207e052d83355d93f4..d01cd69858c702904d64c857d6e08c0ae4e1358d 100644 --- a/Code/OBIA/otbStreamingVectorizedSegmentationOGR.h +++ b/Code/OBIA/otbStreamingVectorizedSegmentationOGR.h @@ -123,8 +123,8 @@ public: itkGetObjectMacro(SegmentationFilter, SegmentationFilterType); - itkSetMacro(FieldName, std::string); - itkGetMacro(FieldName, std::string); + /*itkSetMacro(FieldName, std::string); + itkGetMacro(FieldName, std::string);*/ void SetStartLabel(const LabelPixelType & label) { @@ -146,7 +146,7 @@ private: virtual OGRDataSourceObjectPointerType ProcessTile(); - std::string m_FieldName; + //std::string m_FieldName; LabelPixelType m_TileMaxLabel; LabelPixelType m_StartLabel; typename SegmentationFilterType::Pointer m_SegmentationFilter; @@ -218,6 +218,11 @@ public: this->GetFilter()->SetFileName(fileName); } + void Initialize() + { + this->GetFilter()->Initialize(); + } + protected: /** Constructor */ StreamingVectorizedSegmentationOGR() {} diff --git a/Code/OBIA/otbStreamingVectorizedSegmentationOGR.txx b/Code/OBIA/otbStreamingVectorizedSegmentationOGR.txx index 3fccafaeae1d4e50552807fcc566efd13741dc13..fae0a52ba4192a6c14bdfc995df600f61e241d60 100644 --- a/Code/OBIA/otbStreamingVectorizedSegmentationOGR.txx +++ b/Code/OBIA/otbStreamingVectorizedSegmentationOGR.txx @@ -33,7 +33,7 @@ namespace otb template <class TImageType, class TSegmentationFilter> PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter> -::PersistentStreamingLabelImageToOGRDataFilter() : m_FieldName("DN"), m_TileMaxLabel(0), m_StartLabel(0) +::PersistentStreamingLabelImageToOGRDataFilter() : m_TileMaxLabel(0), m_StartLabel(0) { m_SegmentationFilter = SegmentationFilterType::New(); m_TileNumber = 1; @@ -100,8 +100,6 @@ PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter> itk::TimeProbe chrono1; chrono1.Start(); m_SegmentationFilter->SetInput(extract->GetOutput()); - //m_SegmentationFilter->ResetPipeline(); - //m_SegmentationFilter->Modified(); m_SegmentationFilter->UpdateLargestPossibleRegion(); m_SegmentationFilter->Update(); @@ -110,54 +108,59 @@ PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter> itk::TimeProbe chrono2; chrono2.Start(); - //labelImageToVectorDataFilter->SetInput(dynamic_cast<LabelImageType *>(segFilter->GetOutputs().at(labelImageIndex).GetPointer())); + labelImageToOGRDataFilter->SetInput(dynamic_cast<LabelImageType *>(m_SegmentationFilter->GetOutputs().at(labelImageIndex).GetPointer())); - labelImageToOGRDataFilter->SetFieldName(m_FieldName); + labelImageToOGRDataFilter->SetFieldName(this->GetFieldName()); labelImageToOGRDataFilter->Update(); chrono2.Stop(); std::cout<< "vectorization took " << chrono2.GetTotal() << " sec"<<std::endl; - //Relabel the vector data - /*itk::TimeProbe chrono3; - chrono3.Start(); - typename TreeNodeType::Pointer rootNode = const_cast<TreeNodeType *>(labelImageToVectorDataFilter->GetOutput()->GetDataTree()->GetRoot()); - ChildrenListType childList = rootNode->GetChildrenList()[0]->GetChildrenList(); - std::vector<int> fieldValueVector; - for (typename ChildrenListType::iterator it = childList.begin(); it != childList.end(); ++it) - { - typename OutputVectorDataType::DataNodePointerType dataNode = (*it)->Get(); - fieldValueVector.push_back(dataNode->GetFieldAsInt(m_FieldName)); - } - std::sort(fieldValueVector.begin(), fieldValueVector.end()); - std::map<int,int> relabelMap; + //Relabeling + itk::TimeProbe chrono3; + chrono3.Start(); + OGRDataSourceObjectType * output = const_cast<OGRDataSourceObjectType *>(labelImageToOGRDataFilter->GetOutput()); + OGRDataSource * poDS = output->Get()->GetDataSource(); + OGRLayer * poLayer = poDS->GetLayer(0); + unsigned int nbFeatures = poLayer->GetFeatureCount(true); unsigned int i = 0; unsigned int ind = 0; - for(i = 0; i < fieldValueVector.size(); i++) + OGRFeature *poFeature; + std::map<int,int> relabelMap; + poLayer->ResetReading(); + while (i<nbFeatures) { - if (relabelMap.find(fieldValueVector.at(i)) == relabelMap.end()) + poFeature = poLayer->GetNextFeature(); + int fieldValue = poFeature->GetFieldAsInteger(0); + if (relabelMap.find(fieldValue) == relabelMap.end()) { - relabelMap[fieldValueVector.at(i)] = static_cast<int>(ind); + relabelMap[fieldValue] = static_cast<int>(ind); ind = ind + 1; } + OGRFeature::DestroyFeature( poFeature ); + i++; } - for (typename ChildrenListType::iterator it = childList.begin(); it != childList.end(); ++it) + i = 0; + poLayer->ResetReading(); + while (i<nbFeatures) { - typename OutputVectorDataType::DataNodePointerType dataNode = (*it)->Get(); - int newLabel = relabelMap[dataNode->GetFieldAsInt(m_FieldName)] + m_TileMaxLabel; - dataNode->SetFieldAsInt(m_FieldName, newLabel); + poFeature = poLayer->GetNextFeature(); + int fieldValue = poFeature->GetFieldAsInteger(0); + int newFieldValue = relabelMap[fieldValue] + m_TileMaxLabel; + poFeature->SetField(0,newFieldValue); + poFeature->UnsetField(0); + poFeature->SetField(this->GetFieldName().c_str(),newFieldValue); + //Need to rewrite the feature otherwise changes are not considered. + poLayer->SetFeature(poFeature); + + OGRFeature::DestroyFeature( poFeature ); + i++; } + m_TileMaxLabel = m_TileMaxLabel + relabelMap.size(); + std::cout<< "relabel took " << chrono3.GetTotal() << " sec"<<std::endl; - m_TileMaxLabel = m_TileMaxLabel + fieldValueVector.size(); - - chrono3.Stop(); - //std::cout<< "relabel took " << chrono3.GetTotal() << " sec"<<std::endl; - - - tileChrono.Stop(); - std::cout<< "tile processing took " << tileChrono.GetTotal() << " sec"<<std::endl;*/ - // return the VectorData in image physical coordinates + return output; return const_cast<OGRDataSourceObjectType *>(labelImageToOGRDataFilter->GetOutput()); } diff --git a/Testing/Code/OBIA/otbStreamingVectorizedSegmentationOGR.cxx b/Testing/Code/OBIA/otbStreamingVectorizedSegmentationOGR.cxx index bf6bde307e7866c3b26cd101ccf2aa0738d1a886..1a3bca51d7b37048646cb08b1d249aae472444a3 100644 --- a/Testing/Code/OBIA/otbStreamingVectorizedSegmentationOGR.cxx +++ b/Testing/Code/OBIA/otbStreamingVectorizedSegmentationOGR.cxx @@ -21,6 +21,7 @@ #include "otbImageFileReader.h" #include "otbMeanShiftVectorImageFilter.h" +#include "otbMeanShiftImageFilter.h" #include "itkConnectedComponentFunctorImageFilter.h" #include "otbConnectedComponentMuParserFunctor.h" @@ -53,13 +54,15 @@ int otbStreamingVectorizedSegmentationOGR(int argc, char * argv[]) // Typedefs typedef otb::VectorImage<InputPixelType, Dimension> ImageType; + //typedef otb::Image<InputPixelType, Dimension> ImageType; typedef otb::Image<unsigned int, Dimension> LabelImageType; typedef otb::MeanShiftVectorImageFilter<ImageType, ImageType, LabelImageType> MeanShiftImageFilterType; + //typedef otb::MeanShiftImageFilter<ImageType, ImageType, LabelImageType> MeanShiftImageFilterType; typedef otb::Functor::ConnectedComponentMuParserFunctor<ImageType::PixelType> FunctorType; typedef itk::ConnectedComponentFunctorImageFilter<ImageType, LabelImageType, FunctorType, LabelImageType > SegmentationFilterType; - typedef otb::StreamingVectorizedSegmentationOGR<ImageType, SegmentationFilterType> StreamingVectorizedSegmentationOGRType; - //typedef otb::StreamingVectorizedSegmentationOGR<ImageType, VectorDataType, MeanShiftImageFilterType> StreamingVectorizedSegmentationOGRType; + //typedef otb::StreamingVectorizedSegmentationOGR<ImageType, SegmentationFilterType> StreamingVectorizedSegmentationOGRType; + typedef otb::StreamingVectorizedSegmentationOGR<ImageType, MeanShiftImageFilterType> StreamingVectorizedSegmentationOGRType; typedef otb::ImageFileReader<ImageType> ReaderType; @@ -75,12 +78,13 @@ int otbStreamingVectorizedSegmentationOGR(int argc, char * argv[]) filter->GetStreamer()->SetTileDimensionTiledStreaming(atoi(argv[3])); filter->SetFieldName(fieldName); filter->SetStartLabel(1); - /*filter->GetSegmentationFilter()->SetSpatialRadius(10); + filter->GetSegmentationFilter()->SetSpatialRadius(10); filter->GetSegmentationFilter()->SetRangeRadius(15); - filter->GetSegmentationFilter()->SetMinimumRegionSize(400);*/ - filter->GetSegmentationFilter()->GetFunctor().SetExpression("distance<40"); + filter->GetSegmentationFilter()->SetMinimumRegionSize(400); + //filter->GetSegmentationFilter()->GetFunctor().SetExpression("distance<15"); filter->SetFileName(argv[2]); + filter->Initialize(); //must do this after SetFileName ... filter->Update();