diff --git a/Code/Common/otbDataNode.h b/Code/Common/otbDataNode.h index 3822ad24536de4a3140a334ea41d70258265d755..a72057b190ec8b24139b6846e2fceeebd150c473 100644 --- a/Code/Common/otbDataNode.h +++ b/Code/Common/otbDataNode.h @@ -22,6 +22,7 @@ #include "otbPolyLineParametricPathWithValue.h" #include "otbPolygon.h" #include "otbObjectList.h" +#include "otbVectorDataKeywordlist.h" #include <iostream> @@ -266,6 +267,7 @@ private: /** The fields map */ FieldMapType m_FieldMap; + }; } // end namespace diff --git a/Code/Common/otbDataNode.txx b/Code/Common/otbDataNode.txx index b96ac89bb37fb71bb0d9f6ce01ceda6e6eeb669e..bd21d74087f627785758fe7cf30305c321c1169c 100644 --- a/Code/Common/otbDataNode.txx +++ b/Code/Common/otbDataNode.txx @@ -19,6 +19,8 @@ #define __otbDataNode_txx #include "otbDataNode.h" +#include "otbMetaDataKey.h" +#include "otbVectorDataKeywordlist.h" namespace otb { @@ -170,56 +172,62 @@ DataNode<TPrecision,VDimension,TValuePrecision> itk::OStringStream oss; switch (m_NodeType) { - case ROOT: - { - oss<<"Root ("<<m_NodeId<<")"; - break; - } - case DOCUMENT: - { - oss<<"Document ("<<m_NodeId<<")"; - break; - } - case FOLDER: - { - oss<<"Folder ("<<m_NodeId<<")"; - break; - } - case FEATURE_POINT: - { - oss<<"Point ("<<m_NodeId<<") "<<m_Data.point; - break; - } - case FEATURE_LINE: - { - oss<<"Line ("<<m_NodeId<<") "<<m_Data.line->GetVertexList()->Size()<<" points"; - break; - } - case FEATURE_POLYGON: - { - oss<<"Polygon ("<<m_NodeId<<") "<<this->GetPolygonExteriorRing()->GetVertexList()->Size()<<" points, "<<this->GetPolygonInteriorRings()->Size()<<" interior rings"; - break; - } - case FEATURE_MULTIPOINT: - { - oss<<"MultiPoint ("<<m_NodeId<<")"; - break; - } - case FEATURE_MULTILINE: - { - oss<<"MultiLine ("<<m_NodeId<<")"; - break; - } - case FEATURE_MULTIPOLYGON: - { - oss<<"MultiPolygon ("<<m_NodeId<<")"; - break; + case ROOT: + { + oss<<"Root ("<<m_NodeId<<")"; + break; + } + case DOCUMENT: + { + oss<<"Document ("<<m_NodeId<<")"; + break; + } + case FOLDER: + { + oss<<"Folder ("<<m_NodeId<<")"; + break; + } + case FEATURE_POINT: + { + oss<<"Point ("<<m_NodeId<<") "<<m_Data.point; + break; + } + case FEATURE_LINE: + { + oss<<"Line ("<<m_NodeId<<") "<<m_Data.line->GetVertexList()->Size()<<" points"; + break; + } + case FEATURE_POLYGON: + { + oss<<"Polygon ("<<m_NodeId<<") "<<this->GetPolygonExteriorRing()->GetVertexList()->Size()<<" points, "<<this->GetPolygonInteriorRings()->Size()<<" interior rings"; + break; + } + case FEATURE_MULTIPOINT: + { + oss<<"MultiPoint ("<<m_NodeId<<")"; + break; + } + case FEATURE_MULTILINE: + { + oss<<"MultiLine ("<<m_NodeId<<")"; + break; + } + case FEATURE_MULTIPOLYGON: + { + oss<<"MultiPolygon ("<<m_NodeId<<")"; + break; + } + case FEATURE_COLLECTION: + { + oss<<"Collection ("<<m_NodeId<<")"; + break; + } } - case FEATURE_COLLECTION: + if(GetMetaDataDictionary().HasKey(MetaDataKey::VectorDataKeywordlistKey)) { - oss<<"Collection ("<<m_NodeId<<")"; - break; - } + VectorDataKeywordlist kwl; + itk::ExposeMetaData<VectorDataKeywordlist>(GetMetaDataDictionary(), MetaDataKey::VectorDataKeywordlistKey, kwl); + oss<< "\n -> Metadata: " << kwl; } return oss.str(); } diff --git a/Code/IO/otbSHPVectorDataIO.txx b/Code/IO/otbSHPVectorDataIO.txx index e9df00f9c85c9af7f14d63d6d746bfcaba91a8f7..b0a191ecc355e49b8b07c9a96789403405a19024 100644 --- a/Code/IO/otbSHPVectorDataIO.txx +++ b/Code/IO/otbSHPVectorDataIO.txx @@ -211,17 +211,24 @@ SHPVectorDataIO<TData> if (geometry != NULL) { otb::VectorDataKeywordlist kwl; + std::cout << "Inserting " << feature->GetFieldCount() << " fields." << std::endl; for (int fieldNum=0; fieldNum< feature->GetFieldCount(); ++fieldNum) { - kwl.AddField(feature->GetFieldDefnRef(fieldNum)); + kwl.AddField(feature->GetFieldDefnRef(fieldNum), feature->GetRawFieldRef(fieldNum)); } + switch (geometry->getGeometryType()) { case wkbPoint: { typename InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New(); newNode->Set(ConvertGeometryToPointNode(geometry)); + //Reach the DataNode inside the tree node + itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary(); + itk::EncapsulateMetaData< VectorDataKeywordlist >(dict, + MetaDataKey::VectorDataKeywordlistKey, + kwl); folderPtr->AddChild(newNode); break; } @@ -229,6 +236,11 @@ SHPVectorDataIO<TData> { typename InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New(); newNode->Set(ConvertGeometryToPointNode(geometry)); + //Reach the DataNode inside the tree node + itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary(); + itk::EncapsulateMetaData< VectorDataKeywordlist >(dict, + MetaDataKey::VectorDataKeywordlistKey, + kwl); folderPtr->AddChild(newNode); break; } @@ -236,6 +248,11 @@ SHPVectorDataIO<TData> { typename InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New(); newNode->Set(ConvertGeometryToLineNode(geometry)); + //Reach the DataNode inside the tree node + itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary(); + itk::EncapsulateMetaData< VectorDataKeywordlist >(dict, + MetaDataKey::VectorDataKeywordlistKey, + kwl); folderPtr->AddChild(newNode); break; } @@ -243,6 +260,11 @@ SHPVectorDataIO<TData> { typename InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New(); newNode->Set(ConvertGeometryToLineNode(geometry)); + //Reach the DataNode inside the tree node + itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary(); + itk::EncapsulateMetaData< VectorDataKeywordlist >(dict, + MetaDataKey::VectorDataKeywordlistKey, + kwl); folderPtr->AddChild(newNode); break; } @@ -250,6 +272,11 @@ SHPVectorDataIO<TData> { typename InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New(); newNode->Set(ConvertGeometryToPolygonNode(geometry)); + //Reach the DataNode inside the tree node + itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary(); + itk::EncapsulateMetaData< VectorDataKeywordlist >(dict, + MetaDataKey::VectorDataKeywordlistKey, + kwl); folderPtr->AddChild(newNode); break; } @@ -257,6 +284,11 @@ SHPVectorDataIO<TData> { typename InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New(); newNode->Set(ConvertGeometryToPolygonNode(geometry)); + //Reach the DataNode inside the tree node + itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary(); + itk::EncapsulateMetaData< VectorDataKeywordlist >(dict, + MetaDataKey::VectorDataKeywordlistKey, + kwl); folderPtr->AddChild(newNode); break; } diff --git a/Code/IO/otbVectorDataKeywordlist.cxx b/Code/IO/otbVectorDataKeywordlist.cxx index fe80e6a5fa95c244d7ac71cf038d95ec26c34e1a..b9091d9341bd6919a1c0d9705e7092335b28ab78 100644 --- a/Code/IO/otbVectorDataKeywordlist.cxx +++ b/Code/IO/otbVectorDataKeywordlist.cxx @@ -17,18 +17,13 @@ =========================================================================*/ #include "otbVectorDataKeywordlist.h" +#include <iomanip> namespace otb { -void -VectorDataKeywordlist - ::Print(std::ostream& os) const -{ - os << "[UNKNOWN_PRINT_CHARACTERISTICS]" << std::endl; -} -otb::VectorDataKeywordlist +VectorDataKeywordlist ::VectorDataKeywordlist() { //Nothing to do here @@ -37,14 +32,137 @@ otb::VectorDataKeywordlist VectorDataKeywordlist ::~VectorDataKeywordlist() { - //Nothing to do here + for (unsigned int i = 0; i < m_FieldList.size(); ++i) + { + delete(m_FieldList[i].first); + } } +void VectorDataKeywordlist:: + AddField(OGRFieldDefn* fieldDefn, OGRField* field) +{ + FieldType newField; + newField.first = new OGRFieldDefn(fieldDefn); + newField.second = *field; //FIXME this is only a shallow copy + m_FieldList.push_back(newField); +}; + void VectorDataKeywordlist:: operator=(const Self& p) { - m_FieldList = p.m_FieldList; + for (unsigned int i = 0; i < p.m_FieldList.size(); ++i) + { + FieldType newField; + newField.first = new OGRFieldDefn(p.m_FieldList[i].first); + newField.second = p.m_FieldList[i].second; //FIXME this is only a shallow copy + m_FieldList.push_back(newField); + } +} + +void +VectorDataKeywordlist:: + Print(std::ostream& os, itk::Indent indent) const +{ + this->PrintSelf(os, indent.GetNextIndent()); +} + +void +VectorDataKeywordlist:: + PrintSelf(std::ostream& os, itk::Indent indent) const +{ + os << indent << " VectorData Keyword list: "; + os << indent << " - Size: " << m_FieldList.size() << std::endl; + for (unsigned int i = 0; i < m_FieldList.size(); ++i) + { + os << indent << " " << PrintField(m_FieldList[i]); + } +} + +std::string +VectorDataKeywordlist:: + PrintField(FieldType field) const +{ + std::stringstream output; + output << std::setprecision(15); + output << field.first->GetNameRef() << " ("; + output << field.first->GetFieldTypeName(field.first->GetType()) << "): "; + switch(field.first->GetType()) + { + case OFTInteger: + { + output << field.second.Integer; + break; + } + case OFTIntegerList: + { + output << "Type not handled for printing"; + break; + } + case OFTReal: + { + output << field.second.Real; + break; + } + case OFTRealList: + { + output << "Type not handled for printing"; + break; + } + case OFTString: + { + if (field.second.String != NULL) + { + output << field.second.String; + } + break; + } + case OFTStringList: + { + output << "Type not handled for printing"; + break; + } + case OFTWideString: + { + output << "Type not handled for printing"; + break; + } + case OFTWideStringList: + { + output << "Type not handled for printing"; + break; + } + case OFTBinary: + { + output << "Type not handled for printing"; + break; + } + case OFTDate: + { + output << field.second.Date.Year << field.second.Date.Month << field.second.Date.Day; + break; + } + case OFTTime: + { + output << field.second.Date.Hour << field.second.Date.Minute << field.second.Date.Second; + break; + } + case OFTDateTime: + { + output << field.second.Date.Year << field.second.Date.Month << field.second.Date.Day << "-" + << field.second.Date.Hour << field.second.Date.Minute << field.second.Date.Second; + break; + } + } + output << std::endl; + return output.str(); +} + +std::ostream & + operator<<(std::ostream &os, const VectorDataKeywordlist &kwl) +{ + kwl.Print(os); + return os; } } diff --git a/Code/IO/otbVectorDataKeywordlist.h b/Code/IO/otbVectorDataKeywordlist.h index 184b8a35a3d281bbb761e2abb217bd31e0c677c9..123dfd602244b352ebbecf44190c514b3d942e89 100644 --- a/Code/IO/otbVectorDataKeywordlist.h +++ b/Code/IO/otbVectorDataKeywordlist.h @@ -46,16 +46,13 @@ class VectorDataKeywordlist // /** Run-time type information (and related methods). */ // itkTypeMacro(VectorDataKeywordlist, LightObject); + typedef std::pair<OGRFieldDefn*,OGRField> FieldType; + typedef std::vector< FieldType > FieldListType; - typedef std::vector<OGRFieldDefn> FieldListType; + void AddField(OGRFieldDefn* fieldDefn, OGRField* field); - virtual void Print(std::ostream& os) const; - - void AddField(OGRFieldDefn* field) - { - //Fill up - }; + virtual void Print(std::ostream& os, itk::Indent indent=0) const; VectorDataKeywordlist(); virtual ~VectorDataKeywordlist(); @@ -65,15 +62,18 @@ class VectorDataKeywordlist protected: - + virtual void PrintSelf(std::ostream& os, itk::Indent indent) const; private: + std::string PrintField(FieldType field) const; FieldListType m_FieldList; }; +extern std::ostream & operator<<(std::ostream &os, const VectorDataKeywordlist &kwl); + } #endif diff --git a/Testing/Code/IO/CMakeLists.txt b/Testing/Code/IO/CMakeLists.txt index dfab0038d96ee58f4e9746f987bf267d915aaaf6..c9cf9158f2a1a67d087a9b85d7c0ded674e4166b 100755 --- a/Testing/Code/IO/CMakeLists.txt +++ b/Testing/Code/IO/CMakeLists.txt @@ -1531,9 +1531,18 @@ ADD_TEST(ioTvSHPVectorDataFileReader ${IO_TESTS15} ${TEMP}/ioSHPVectorDataFileReader.txt otbVectorDataFileReader ${LARGEDATA}/TOULOUSE/QuickBird/GIS_FILES/000000128955_01_ORDER_SHAPE.shp - ${TEMP}/ioSHPVectorDataFileReader.txt) + ${TEMP}/ioSHPVectorDataFileReader.txt +) ENDIF(OTB_DATA_USE_LARGEINPUT) +ADD_TEST(ioTvSHPVectorDataFileReader2 ${IO_TESTS15} + --compare-ascii ${TOL} ${BASELINE_FILES}/ioSHPVectorDataFileReader2.txt + ${TEMP}/ioSHPVectorDataFileReader2.txt + otbVectorDataFileReader + ${INPUTDATA}/ToulouseRoad-examples.shp + ${TEMP}/ioSHPVectorDataFileReader2.txt +) + ADD_TEST(ioTuVectorDataFileWriterNew ${IO_TESTS15} otbVectorDataFileWriterNew ) @@ -1730,7 +1739,7 @@ ADD_TEST(ioTuImageIOFactoryNew ${IO_TESTS17} otbImageIOFactoryNew ) # --- otb::DEMToOrthoImageGenerator --- -ADD_TEST(ioTuDEMToOrthoImageGeneratorNew ${IO_TESTS17} +ADD_TEST(ioTuDEMToOrthoImageGeneratorNew ${IO_TESTS17} otbDEMToOrthoImageGeneratorNew ) ADD_TEST(ioTvDEMToOrthoImageGeneratorTest ${IO_TESTS17}