/* * 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 otbAttributesMapLabelObject_h #define otbAttributesMapLabelObject_h #if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #include "itkShapeLabelObject.h" #pragma GCC diagnostic pop #else #include "itkShapeLabelObject.h" #endif #include "otbPolygon.h" #include #include namespace otb { namespace Functor { /** \class AttributesMapLabelObjectAccessor * \brief Allows accessing a given field of an AttributesMapLabelObject * * The name of the attribute to retrieve can be set by using the * SetAttributeName method. * * \sa AttributesMapLabelObject * * \ingroup OTBLabelMap */ template class ITK_EXPORT AttributesMapLabelObjectAccessor { public: // The Label Object typedef typedef TLabelObject LabelObjectType; typedef typename LabelObjectType::AttributesValueType AttributeValueType; /** * Please note that no exception catching is done here. * \param labelObject The pointer to the label object * \return The attribute value. */ inline const AttributeValueType operator()(LabelObjectType* labelObject) const { return labelObject->GetAttribute(m_AttributeName.c_str()); } /// Set the name of the attribute to retrieve void SetAttributeName(const char* name) { m_AttributeName = name; } /// Get the the name of the attribute to retrieve const char* GetAttributeName() const { return m_AttributeName.c_str(); } /// Constructor AttributesMapLabelObjectAccessor() : m_AttributeName("") { } /// Destructor ~AttributesMapLabelObjectAccessor() { } private: /// Name of the attribute to retrieve std::string m_AttributeName; }; /** \class AttributesMapMeasurementFunctor * \brief This class allows building a measurement vector from an AttributesMapLabelObject * * It Allows selecting only a subset of the available attributes. * * \ingroup OTBLabelMap */ template class AttributesMapMeasurementFunctor { public: typedef std::vector AttributesListType; inline TMeasurementVector operator()(const TLabelObject* object) const { TMeasurementVector newSample(m_Attributes.size()); unsigned int attrIndex = 0; typename AttributesListType::const_iterator attrIt = m_Attributes.begin(); while (attrIt != m_Attributes.end()) { newSample[attrIndex] = object->GetAttribute(attrIt->c_str()); ++attrIt; ++attrIndex; } return newSample; } /** Add an attribute to the exported attributes list */ void AddAttribute(const char* attr) { m_Attributes.push_back(attr); } /** Remove an attribute from the exported attributes list */ void RemoveAttribute(const char* attr) { AttributesListType::iterator elt = std::find(m_Attributes.begin(), m_Attributes.end(), attr); if (elt != m_Attributes.end()) { m_Attributes.erase(elt); } } /** Remove all attributes from the exported attributes list */ void ClearAttributes() { m_Attributes.clear(); } /** Get The number of exported attributes */ unsigned int GetNumberOfAttributes() { return m_Attributes.size(); } private: AttributesListType m_Attributes; }; } // end namespace Functor /** \class AttributesMapLabelObject * \brief A LabelObject with a generic attributes map * * This class derives from itk::LabelObject and extends it to * store pairs of key, value (of type TAttributesValue) in an internal * map container. * * As such it allows storing any custom attributes as necessary. * * \sa LabelObject, ShapeLabelObject, StatisticsLabelObject * * \ingroup DataRepresentation * * \ingroup OTBLabelMap */ template class ITK_EXPORT AttributesMapLabelObject : public itk::LabelObject { public: /** Standard class typedefs */ typedef AttributesMapLabelObject Self; typedef itk::LabelObject Superclass; typedef typename Superclass::LabelObjectType LabelObjectType; typedef itk::SmartPointer Pointer; typedef itk::SmartPointer ConstPointer; typedef itk::WeakPointer ConstWeakPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro(AttributesMapLabelObject, LabelObject); itkStaticConstMacro(ImageDimension, unsigned int, VImageDimension); /// Type of a label map using an AttributesMapLabelObject typedef itk::LabelMap LabelMapType; /// Template parameters typedef typedef TLabel LabelType; typedef TAttributesValue AttributesValueType; // Convenient inherited typedefs typedef typename Superclass::IndexType IndexType; typedef typename Superclass::LineType LineType; typedef typename Superclass::LengthType LengthType; /// Map container typedefs typedef std::map AttributesMapType; typedef typename AttributesMapType::iterator AttributesMapIteratorType; typedef typename AttributesMapType::const_iterator AttributesMapConstIteratorType; // The polygon corresponding to the label object typedef Polygon PolygonType; typedef typename PolygonType::Pointer PolygonPointerType; /** * Set an attribute value. * If the key name already exists in the map, the value is overwritten. */ void SetAttribute(const char* name, AttributesValueType value) { m_Attributes[name] = value; } /** * Set an attribute value. * If the key name already exists in the map, the value is overwritten. */ void SetAttribute(const std::string& name, AttributesValueType value) { this->SetAttribute(name.c_str(), value); } /** * Returns the attribute corresponding to name */ AttributesValueType GetAttribute(const char* name) const { AttributesMapConstIteratorType it = m_Attributes.find(name); if (it != m_Attributes.end()) { return it->second; } else { itkExceptionMacro(<< "Could not find attribute named " << name); } } /** * Returns the total number of attributes */ unsigned int GetNumberOfAttributes() const { return m_Attributes.size(); } /** * Returns the list of available attributes */ std::vector GetAvailableAttributes() const { std::vector attributesNames; AttributesMapConstIteratorType it = m_Attributes.begin(); while (it != m_Attributes.end()) { attributesNames.push_back(it->first); ++it; } return attributesNames; } /** * This method is overloaded to add the copy of the attributes map. */ virtual void CopyAttributesFrom(const LabelObjectType* lo) { Superclass::CopyAttributesFrom(lo); // copy the data of the current type if possible const Self* src = dynamic_cast(lo); if (src == nullptr) { return; } m_Attributes = src->m_Attributes; } /** Return the polygon (const version) */ const PolygonType* GetPolygon() const { return m_Polygon; } /** Return the polygon (non const version) */ PolygonType* GetPolygon() { return m_Polygon; } /** Set the polygon */ void SetPolygon(PolygonType* p) { m_Polygon = p; } protected: /** Constructor */ AttributesMapLabelObject() : m_Attributes(), m_Polygon(PolygonType::New()) { } /** Destructor */ ~AttributesMapLabelObject() override { } /** The printself method */ void PrintSelf(std::ostream& os, itk::Indent indent) const override { Superclass::PrintSelf(os, indent); os << indent << "Attributes: " << std::endl; for (AttributesMapConstIteratorType it = m_Attributes.begin(); it != m_Attributes.end(); ++it) { os << indent << indent << it->first << " = " << it->second << std::endl; } } private: AttributesMapLabelObject(const Self&) = delete; void operator=(const Self&) = delete; /** The attributes map */ AttributesMapType m_Attributes; /** The polygon corresponding to the label object. Caution, this * will be empty by default */ PolygonPointerType m_Polygon; }; } // end namespace otb #endif