/* * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES) * * This file is part of Orfeo Toolbox * * https://www.orfeo-toolbox.org/ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef otbDataNode_hxx #define otbDataNode_hxx #include "otbDataNode.h" #include "otbMetaDataKey.h" namespace otb { template DataNode::DataNode() { m_NodeType = ROOT; m_NodeId = ""; m_Data.valid = false; } template void DataNode::SetNodeType(NodeType type) { m_NodeType = type; m_Data.valid = false; } template void DataNode::SetPoint(PointType point) { m_NodeType = FEATURE_POINT; m_Data.point = point; m_Data.valid = true; } template void DataNode::SetLine(LineType* line) { m_NodeType = FEATURE_LINE; m_Data.line = line; m_Data.valid = true; } template void DataNode::SetPolygonExteriorRing(PolygonType* polygon) { m_NodeType = FEATURE_POLYGON; m_Data.exteriorRing = polygon; if (!m_Data.interiorRings) { m_Data.interiorRings = PolygonListType::New(); } m_Data.valid = true; } template void DataNode::SetPolygonInteriorRings(PolygonListType* polygonList) { m_NodeType = FEATURE_POLYGON; m_Data.interiorRings = polygonList; if (!m_Data.exteriorRing) { m_Data.exteriorRing = PolygonType::New(); } m_Data.valid = true; } template typename DataNode::PointType DataNode::GetPoint() const { if (!IsPointFeature()) { itkGenericExceptionMacro(<< "Node " << m_NodeId << " is not a point."); } if (!m_Data.valid) { itkGenericExceptionMacro(<< "Invalid point node."); } return m_Data.point; } template typename DataNode::LinePointerType DataNode::GetLine() const { if (!IsLineFeature()) { itkGenericExceptionMacro(<< "Node " << m_NodeId << " is not a line."); } if (!m_Data.valid) { itkGenericExceptionMacro(<< "Invalid line node."); } return m_Data.line; } template typename DataNode::PolygonPointerType DataNode::GetPolygonExteriorRing() const { if (!IsPolygonFeature()) { itkGenericExceptionMacro(<< "Node " << m_NodeId << " is not a polygon."); } if (!m_Data.valid || !m_Data.exteriorRing) { itkGenericExceptionMacro(<< "Invalid polygon node."); } return m_Data.exteriorRing; } template typename DataNode::PolygonListPointerType DataNode::GetPolygonInteriorRings() const { if (!IsPolygonFeature()) { itkGenericExceptionMacro(<< "Node " << m_NodeId << " is not a polygon."); } if (!m_Data.valid || !m_Data.interiorRings) { itkGenericExceptionMacro(<< "Invalid polygon node."); } return m_Data.interiorRings; } template void DataNode::PrintSelf(std::ostream& os, itk::Indent indent) const { os << indent << this->GetNodeTypeAsString(); } template std::string DataNode::GetNodeTypeAsString() const { std::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 FEATURE_COLLECTION: { oss << "Collection (" << m_NodeId << ")"; break; } } if (GetMetaDataDictionary().HasKey(MetaDataKey::VectorDataKeywordlistKey)) { VectorDataKeywordlist kwl; itk::ExposeMetaData(GetMetaDataDictionary(), MetaDataKey::VectorDataKeywordlistKey, kwl); oss << "\n -> Metadata: " << kwl; } return oss.str(); } /* template void DataNode ::SetField(const std::string& key, const std::string& value) { m_FieldMap[key] = value; } */ template void DataNode::SetFieldAsString(const std::string& key, const std::string& value) { otb::VectorDataKeywordlist kwl; itk::ExposeMetaData(this->GetMetaDataDictionary(), MetaDataKey::VectorDataKeywordlistKey, kwl); kwl.SetFieldAsString(key, value); itk::EncapsulateMetaData(this->GetMetaDataDictionary(), MetaDataKey::VectorDataKeywordlistKey, kwl); } template void DataNode::SetFieldAsInt(const std::string& key, int value) { otb::VectorDataKeywordlist kwl; itk::ExposeMetaData(this->GetMetaDataDictionary(), MetaDataKey::VectorDataKeywordlistKey, kwl); kwl.SetFieldAsInt(key, value); itk::EncapsulateMetaData(this->GetMetaDataDictionary(), MetaDataKey::VectorDataKeywordlistKey, kwl); } template void DataNode::SetFieldAsDouble(const std::string& key, double value) { otb::VectorDataKeywordlist kwl; itk::ExposeMetaData(this->GetMetaDataDictionary(), MetaDataKey::VectorDataKeywordlistKey, kwl); kwl.SetFieldAsDouble(key, value); itk::EncapsulateMetaData(this->GetMetaDataDictionary(), MetaDataKey::VectorDataKeywordlistKey, kwl); } template double DataNode::GetFieldAsDouble(const std::string& key) const { VectorDataKeywordlist keywordlist; if (HasField(key)) { itk::ExposeMetaData(this->GetMetaDataDictionary(), MetaDataKey::VectorDataKeywordlistKey, keywordlist); return keywordlist.GetFieldAsDouble(key); } return 0; } /* template std::string DataNode ::GetField(const std::string& key) const { if (HasField(key)) { return (*m_FieldMap.find(key)).second; } else { return "Unknown Key"; } }*/ template std::string DataNode::GetFieldAsString(const std::string& key) const { VectorDataKeywordlist keywordlist; if (HasField(key)) { itk::ExposeMetaData(this->GetMetaDataDictionary(), MetaDataKey::VectorDataKeywordlistKey, keywordlist); return keywordlist.GetFieldAsString(key); } return ""; } template int DataNode::GetFieldAsInt(const std::string& key) const { VectorDataKeywordlist keywordlist; if (HasField(key)) { itk::ExposeMetaData(this->GetMetaDataDictionary(), MetaDataKey::VectorDataKeywordlistKey, keywordlist); return keywordlist.GetFieldAsInt(key); } return 0; } /* template void DataNode ::RemoveField(const std::string& key) { m_FieldMap.erase(key); } template bool DataNode ::HasField(const std::string& key) const { return (m_FieldMap.find(key)!=m_FieldMap.end()); } */ template bool DataNode::HasField(const std::string& key) const { VectorDataKeywordlist keywordlist; if (this->GetMetaDataDictionary().HasKey(MetaDataKey::VectorDataKeywordlistKey)) { itk::ExposeMetaData(this->GetMetaDataDictionary(), MetaDataKey::VectorDataKeywordlistKey, keywordlist); return keywordlist.HasField(key); } return false; } /* template typename DataNode ::FieldType DataNode ::GetNthField(unsigned int index) const { if (index unsigned int DataNode ::GetNumberOfFields() const { return m_FieldMap.size(); } */ template void DataNode::CopyFieldList(const DataNode* dataNode) { // The source keywordlist where to get the feature list to copy otb::VectorDataKeywordlist srcKwl; itk::ExposeMetaData(dataNode->GetMetaDataDictionary(), MetaDataKey::VectorDataKeywordlistKey, srcKwl); otb::VectorDataKeywordlist kwl; itk::ExposeMetaData(this->GetMetaDataDictionary(), MetaDataKey::VectorDataKeywordlistKey, kwl); kwl.CopyFieldList(srcKwl); itk::EncapsulateMetaData(this->GetMetaDataDictionary(), MetaDataKey::VectorDataKeywordlistKey, kwl); } template std::vector DataNode::GetFieldList() const { VectorDataKeywordlist keywordlist; if (this->GetMetaDataDictionary().HasKey(MetaDataKey::VectorDataKeywordlistKey)) { itk::ExposeMetaData(this->GetMetaDataDictionary(), MetaDataKey::VectorDataKeywordlistKey, keywordlist); return keywordlist.GetFieldList(); } std::vector empty; return empty; } /* template void DataNode ::ClearFields() { m_FieldMap.clear(); }*/ template bool DataNode::IsDocument() const { return m_NodeType == DOCUMENT; } template bool DataNode::IsRoot() const { return m_NodeType == ROOT; } template bool DataNode::IsFolder() const { return m_NodeType == FOLDER; } template bool DataNode::IsPointFeature() const { return m_NodeType == FEATURE_POINT; } template bool DataNode::IsLineFeature() const { return m_NodeType == FEATURE_LINE; } template bool DataNode::IsPolygonFeature() const { return m_NodeType == FEATURE_POLYGON; } template bool DataNode::IsMultiPointFeature() const { return m_NodeType == FEATURE_MULTIPOINT; } template bool DataNode::IsMultiLineFeature() const { return m_NodeType == FEATURE_MULTILINE; } template bool DataNode::IsMultiPolygonFeature() const { return m_NodeType == FEATURE_MULTIPOLYGON; } template bool DataNode::IsCollectionFeature() const { return m_NodeType == FEATURE_COLLECTION; } template OGRGeometry* DataNode::ConvertDataNodeToOGRGeometry(const DataNode* dataNode) { switch (dataNode->GetNodeType()) { case FEATURE_POINT: { OGRPoint* ogrPoint = (OGRPoint*)OGRGeometryFactory::createGeometry(wkbPoint); ogrPoint->setX(dataNode->GetPoint()[0]); ogrPoint->setY(dataNode->GetPoint()[1]); return ogrPoint; } break; case FEATURE_LINE: { // Build the ogrObject OGRLineString* ogrLine = (OGRLineString*)OGRGeometryFactory::createGeometry(wkbLineString); VertexListConstPointerType vertexList = dataNode->GetLine()->GetVertexList(); typename VertexListType::ConstIterator vIt = vertexList->Begin(); while (vIt != vertexList->End()) { OGRPoint ogrPoint; ogrPoint.setX(vIt.Value()[0]); ogrPoint.setY(vIt.Value()[1]); if (Dimension > 2) { ogrPoint.setZ(vIt.Value()[2]); } ogrLine->addPoint(&ogrPoint); ++vIt; } return ogrLine; } break; case FEATURE_POLYGON: { OGRPolygon* polygon = (OGRPolygon*)OGRGeometryFactory::createGeometry(wkbPolygon); OGRLinearRing* ogrExternalRing = (OGRLinearRing*)OGRGeometryFactory::createGeometry(wkbLinearRing); VertexListConstPointerType vertexList = dataNode->GetPolygonExteriorRing()->GetVertexList(); typename VertexListType::ConstIterator vIt = vertexList->Begin(); while (vIt != vertexList->End()) { OGRPoint ogrPoint; ogrPoint.setX(vIt.Value()[0]); ogrPoint.setY(vIt.Value()[1]); if (Dimension > 2) { ogrPoint.setZ(vIt.Value()[2]); } ogrExternalRing->addPoint(&ogrPoint); ++vIt; } polygon->addRing(ogrExternalRing); // Close the polygon polygon->closeRings(); OGRGeometryFactory::destroyGeometry(ogrExternalRing); return polygon; } break; default: break; } return nullptr; } template double DataNode::EuclideanDistanceMetric(const DataNode* node) { // Convert the nodes to OGRGeometries OGRGeometry* dstGeomtery = this->ConvertDataNodeToOGRGeometry(node); OGRGeometry* currentGeometry = this->ConvertDataNodeToOGRGeometry(this); // Compute the distance return currentGeometry->Distance(dstGeomtery); } template double DataNode::EuclideanDistanceMetric(const PointType point) { // Convert Point to point to ogrPoint OGRPoint ogrPointSrc; ogrPointSrc.setX(point[0]); ogrPointSrc.setY(point[1]); // Convert the current datanode to an OGRGeometry OGRGeometry* currentGeometry = this->ConvertDataNodeToOGRGeometry(this); // return the distance return currentGeometry->Distance(&ogrPointSrc); } template bool DataNode::Intersects(const DataNode* node) { // Convert the nodes to OGRGeometries OGRGeometry* dstGeomtery = this->ConvertDataNodeToOGRGeometry(node); OGRGeometry* currentGeometry = this->ConvertDataNodeToOGRGeometry(this); // return currentGeometry->Intersects(dstGeomtery); } template bool DataNode::Within(const DataNode* node) { // Convert the nodes to OGRGeometries OGRGeometry* dstGeomtery = this->ConvertDataNodeToOGRGeometry(node); OGRGeometry* currentGeometry = this->ConvertDataNodeToOGRGeometry(this); // return currentGeometry->Within(dstGeomtery); } } // end namespace otb #endif