From 16b6360e7792a9232d0de1bad11fb84d0235bd8f Mon Sep 17 00:00:00 2001
From: Julien Michel <julien.michel@c-s.fr>
Date: Mon, 4 Dec 2006 18:27:48 +0000
Subject: [PATCH] =?UTF-8?q?Encapsulation=20des=20it=C3=A9rateurs=20de=20so?=
 =?UTF-8?q?mmets=20en=20vue=20d'une=20int=C3=A9gration=20plus=20propre=20d?=
 =?UTF-8?q?e=20boost.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 Code/SpatialReasoning/otbRCC8Graph.h          |  19 +-
 Code/SpatialReasoning/otbRCC8Graph.txx        |   6 +-
 Code/SpatialReasoning/otbRCC8VertexIterator.h | 109 ++++++++++++
 .../otbRCC8VertexIterator.txx                 | 165 ++++++++++++++++++
 Testing/Code/SpatialReasoning/CMakeLists.txt  |   3 +-
 .../Code/SpatialReasoning/otbRCC8Graph.cxx    |  59 ++++++-
 6 files changed, 346 insertions(+), 15 deletions(-)
 create mode 100644 Code/SpatialReasoning/otbRCC8VertexIterator.h
 create mode 100644 Code/SpatialReasoning/otbRCC8VertexIterator.txx

diff --git a/Code/SpatialReasoning/otbRCC8Graph.h b/Code/SpatialReasoning/otbRCC8Graph.h
index 03a881d18a..52e0657347 100644
--- a/Code/SpatialReasoning/otbRCC8Graph.h
+++ b/Code/SpatialReasoning/otbRCC8Graph.h
@@ -64,13 +64,14 @@ public:
   /** Edge typedef */
   typedef RCC8Edge EdgeType;
   typedef typename EdgeType::Pointer EdgePointerType;
+  typedef typename EdgeType::RCC8ValueType RCC8ValueType;
   /** Typedef for the boost graph representation */
   typedef boost::adjacency_list
   <boost::vecS,boost::vecS,boost::bidirectionalS,
-   VertexPointerType,EdgePointerType> GraphType;
+   VertexPointerType,EdgePointerType> InternalGraphType;
   /** Edges and vertices descriptors typedefs (boost objects)*/
-  typedef typename GraphType::vertex_descriptor  VertexDescriptorType;
-  typedef typename GraphType::edge_descriptor    EdgeDescriptorType;
+  typedef typename InternalGraphType::vertex_descriptor  VertexDescriptorType;
+  typedef typename InternalGraphType::edge_descriptor    EdgeDescriptorType;
   /** Getters and Setters for the number of vertices */
   itkSetMacro(NumberOfVertices,int);
   itkGetConstReferenceMacro(NumberOfVertices,int);
@@ -78,7 +79,7 @@ public:
    *  Return the internal boost graph object.
    *  \return The internal boost graph object
    */
-  GraphType GetGraph(void){return m_Graph;};
+  InternalGraphType GetGraph(void){return m_Graph;};
   /**
    * Since the number of vertices is mandatory to instantiate the
    * internal boost representation, the build method has to be called
@@ -103,8 +104,12 @@ public:
    * \param index2 The index of the target vertex.
    * \param edge The edge.
    */
-  void AddEdge(unsigned int index1, unsigned int index2, EdgePointerType edge);
-
+  void AddEdge(unsigned int index1, unsigned int index2, RCC8ValueType r);
+  
+  /**
+   * \class EdgeIterator
+   * \brief Iterates on the graph edges
+   */
 protected:
   /** Constructor */
   RCC8Graph();
@@ -118,7 +123,7 @@ private:
   /** Defines the number of vertices (ie total number of segmentation regions)*/
   int m_NumberOfVertices;
   /** Internal representation using the boost graph library */
-  GraphType m_Graph;
+  InternalGraphType m_Graph;
 };
 } // end namespace otb
 
diff --git a/Code/SpatialReasoning/otbRCC8Graph.txx b/Code/SpatialReasoning/otbRCC8Graph.txx
index 57fa3824a2..5cca73ca17 100644
--- a/Code/SpatialReasoning/otbRCC8Graph.txx
+++ b/Code/SpatialReasoning/otbRCC8Graph.txx
@@ -73,14 +73,16 @@ namespace otb
    * Add an edge in the graph.
    * \param index1 The index of the source vertex. 
    * \param index2 The index of the target vertex.
-   * \param edge The edge.
+   * \param r The rcc8 value associated to the edge.
    */
   template <class TVertex>
   void
   RCC8Graph<TVertex>
-  ::AddEdge(unsigned int index1, unsigned int index2, EdgePointerType edge)
+  ::AddEdge(unsigned int index1, unsigned int index2, RCC8ValueType r)
   {
     EdgeDescriptorType e = boost::add_edge(index1,index2,m_Graph).first;
+    EdgeType::Pointer edge = EdgeType::New();
+    edge->SetValue(r);
     m_Graph[e]=edge;
   }
   /**
diff --git a/Code/SpatialReasoning/otbRCC8VertexIterator.h b/Code/SpatialReasoning/otbRCC8VertexIterator.h
new file mode 100644
index 0000000000..cf6674e75b
--- /dev/null
+++ b/Code/SpatialReasoning/otbRCC8VertexIterator.h
@@ -0,0 +1,109 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even 
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef _otbRCC8VertexIterator_h
+#define _otbRCC8VertexIterator_h
+
+#include "otbRCC8Graph.h"
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/adjacency_list.hpp>
+
+namespace otb
+{
+/**
+ * \class VertexIterator
+ * \brief Iterates on the graph vertices
+ */
+template <class TGraph>
+class RCC8VertexIterator 
+{
+ public:
+  /** self typedef */
+  typedef RCC8VertexIterator Self;
+
+  /** Graph typedef */
+  typedef TGraph GraphType;
+  typedef typename GraphType::InternalGraphType InternalGraphType;
+  typedef typename GraphType::Pointer GraphPointerType;
+  typedef typename GraphType::VertexPointerType VertexPointerType;
+  /** typedef of the internal iterator */
+  typedef typename boost::graph_traits<InternalGraphType>::vertex_iterator InternalIteratorType;
+
+  /** Constructor */
+  RCC8VertexIterator();  
+   /** Copy constructor */
+   RCC8VertexIterator(const Self& iter);
+   /**  Constructor with input graph */
+   RCC8VertexIterator(TGraph * graph);
+  /**
+   * Get the current vertex.
+   * \return The current vertex pointed by the iterator.
+   */
+  VertexPointerType Get(void);
+   /** 
+    * Return true if the iterator is at the end.
+    * \return True if the iterator is at the end.
+    */
+   bool IsAtEnd(void);
+   /**
+    * Go to the beginning.
+    */
+   void GoToBegin(void);
+  /**
+   * Increment.
+   */
+  Self& operator++();
+  /**
+   * Decrement.
+   */
+  Self& operator--();
+  /**
+   * Add
+   */
+  Self& operator+(int i);
+
+  /**
+   * Remove
+   */
+  Self& operator-(int i);
+  /**
+   * Difference comparison operator.
+   */
+  bool operator!=(const Self& it);
+  /**
+   * Equality comparison operator.
+   */
+  bool operator==(const Self& it);
+  /**
+   * Instantiation operator.
+   */
+  Self& operator=(const Self& it);
+ private:
+  // End
+  InternalIteratorType m_End;
+  // Internal iterator.
+  InternalIteratorType m_Iter;
+  // Input graph pointer
+  GraphPointerType m_Graph;
+};
+} // End namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbRCC8VertexIterator.txx"
+#endif
+
+#endif
diff --git a/Code/SpatialReasoning/otbRCC8VertexIterator.txx b/Code/SpatialReasoning/otbRCC8VertexIterator.txx
new file mode 100644
index 0000000000..4232e151e2
--- /dev/null
+++ b/Code/SpatialReasoning/otbRCC8VertexIterator.txx
@@ -0,0 +1,165 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even 
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef _otbRCC8VertexIterator_txx
+#define _otbRCC8VertexIterator_txx
+
+
+namespace otb
+{
+
+ /** Constructor */
+  template <class TGraph>
+  RCC8VertexIterator<TGraph>
+  ::RCC8VertexIterator()
+  {}
+  /**
+   * Copy operator.
+   */
+  template <class TGraph>
+  RCC8VertexIterator<TGraph>
+  ::RCC8VertexIterator(const Self& iter)
+  {
+    m_Iter=iter.m_Iter;
+    m_Graph=iter.m_Graph;
+    m_End=iter.m_End;
+  }
+  /**  
+   *Constructor with input graph 
+   */
+  template <class TGraph>
+  RCC8VertexIterator<TGraph>
+  ::RCC8VertexIterator(TGraph * graph) 
+  {
+    m_Graph=graph;
+    tie(m_Iter,m_End)=vertices(m_Graph->GetGraph());
+  }
+  /**
+   * Get the current object.
+   * \return The current object pointed by the iterator.
+   */
+  template <class TGraph>
+  typename  RCC8VertexIterator<TGraph>
+  ::VertexPointerType 
+  RCC8VertexIterator<TGraph>
+  ::Get(void)
+  {
+    return (m_Graph->GetGraph())[*m_Iter];
+  }
+  /** 
+    * Return true if the iterator is at the end.
+    * \return True if the iterator is at the end.
+    */
+  template <class TGraph>
+  bool
+  RCC8VertexIterator<TGraph>
+  ::IsAtEnd(void)
+  {
+    return (m_Iter==m_End);
+  }
+  /**
+   * Go to the beginning.
+   */
+  template <class TGraph>
+  void 
+  RCC8VertexIterator<TGraph>
+  ::GoToBegin(void)
+  {
+    tie(m_Iter,m_End)=vertices(m_Graph->GetGraph());
+  }
+  /**
+   * Increment.
+   */
+  template <class TGraph>
+  typename RCC8VertexIterator<TGraph> 
+  ::Self& 
+  RCC8VertexIterator<TGraph>
+  ::operator++()
+  {
+    ++m_Iter;
+    return *this;
+  }
+  /**
+   * Decrement.
+   */
+  template <class TGraph>
+  typename RCC8VertexIterator<TGraph> 
+  ::Self& 
+  RCC8VertexIterator<TGraph>
+  ::operator--()
+  {
+    --m_Iter;
+    return *this;
+  } 
+  /**
+   * Add
+   */
+  template <class TGraph>
+  typename RCC8VertexIterator<TGraph> 
+  ::Self& 
+  RCC8VertexIterator<TGraph>
+  ::operator+(int i)
+  {
+    m_Iter=m_Iter+i;
+    return *this;
+  }
+  /**
+   * Remove
+   */
+  template <class TGraph>
+  typename RCC8VertexIterator<TGraph> 
+  ::Self& 
+  RCC8VertexIterator<TGraph>
+  ::operator-(int i)
+  {
+    m_Iter=m_Iter-i;
+    return *this;
+  }
+  /**
+   * Difference comparison operator.
+   */
+  template <class TGraph>
+  bool 
+  RCC8VertexIterator<TGraph>
+  ::operator!=(const Self& iter)
+  {
+    return (m_Iter != iter.m_Iter);
+  }
+  /**
+   * Equality comparison operator.
+   */
+  template <class TGraph>
+  bool 
+  RCC8VertexIterator<TGraph>
+  ::operator==(const Self& iter)
+  {
+    return (m_Iter == iter.m_Iter);
+  }
+  /**
+   * Instantiation operator.
+   */
+  template <class TGraph>
+  typename RCC8VertexIterator<TGraph> 
+  ::Self& 
+  RCC8VertexIterator<TGraph>
+  ::operator=(const Self& iter)
+  {
+    m_Iter = iter.m_Iter;
+    return *this;
+  }
+} // End namespace otb
+#endif
diff --git a/Testing/Code/SpatialReasoning/CMakeLists.txt b/Testing/Code/SpatialReasoning/CMakeLists.txt
index ce77bab0ab..8ef9b73244 100644
--- a/Testing/Code/SpatialReasoning/CMakeLists.txt
+++ b/Testing/Code/SpatialReasoning/CMakeLists.txt
@@ -72,8 +72,7 @@ ADD_TEST(srTuRCC8GraphNew ${SPATIALREASONING_TESTS}
          otbRCC8GraphNew)
 
 ADD_TEST(srTvRCC8Graph ${SPATIALREASONING_TESTS} 
-         otbRCC8Graph
-	 20	 
+         otbRCC8Graph	 
 	 )
 
 # -------            otb::RCC8GraphSource   --------------------------
diff --git a/Testing/Code/SpatialReasoning/otbRCC8Graph.cxx b/Testing/Code/SpatialReasoning/otbRCC8Graph.cxx
index 5bccd825a9..1f47bfc9ca 100644
--- a/Testing/Code/SpatialReasoning/otbRCC8Graph.cxx
+++ b/Testing/Code/SpatialReasoning/otbRCC8Graph.cxx
@@ -18,6 +18,7 @@
 #include "itkExceptionObject.h"
 #include "otbRCC8Graph.h"
 #include "otbRCC8VertexBase.h"
+#include "otbRCC8VertexIterator.h"
 
 bool fail(bool test, char * reason)
 {
@@ -33,12 +34,14 @@ int otbRCC8Graph(int argc, char* argv[])
 try
   {
     const unsigned int Dimension = 2;
-    unsigned int nbVertices = atoi(argv[1]);
+    const unsigned int nbVertices = 3;
    
     typedef unsigned short  LabelType;
     typedef otb::RCC8VertexBase<LabelType> VertexType;
     typedef otb::RCC8Graph<VertexType> RCC8GraphType;
     typedef RCC8GraphType::EdgeType EdgeType;
+    typedef otb::RCC8VertexIterator<RCC8GraphType> VertexIteratorType;
+    // typedef RCC8GraphType::EdgeIterator   EdgeIteratorType;
     
     // Instantiation
     RCC8GraphType::Pointer rcc8Graph = RCC8GraphType::New();
@@ -52,12 +55,17 @@ try
     // Testing the set vertex method
     VertexType::Pointer vertex1 = VertexType::New();    
     VertexType::Pointer vertex2 = VertexType::New();
+    VertexType::Pointer vertex3 = VertexType::New();
     vertex1->SetSegmentationImageIndex(0);
     vertex1->SetObjectLabelInImage(1);
     vertex2->SetSegmentationImageIndex(1);
     vertex2->SetObjectLabelInImage(2);
+    vertex3->SetSegmentationImageIndex(2);
+    vertex3->SetObjectLabelInImage(3);
+
     rcc8Graph->SetVertex(0,vertex1);
     rcc8Graph->SetVertex(1,vertex2);
+    rcc8Graph->SetVertex(2,vertex3);
     fail(rcc8Graph->GetVertex(0)->GetSegmentationImageIndex()!=0,
 	 "rcc8Graph->GetVertex(0)->GetSegmentationImageIndex()!=0");
     fail(rcc8Graph->GetVertex(0)->GetObjectLabelInImage()!=1,
@@ -66,9 +74,52 @@ try
 	 "rcc8Graph->GetVertex(1)->GetSegmentationImageIndex()!=1");
     fail(rcc8Graph->GetVertex(1)->GetObjectLabelInImage()!=2,
 	 "rcc8Graph->GetVertex(1)->GetObjectLabelInImgage()!=2");
-    EdgeType::Pointer edge = EdgeType::New();
-    edge->SetValue(otb::OTB_RCC8_NTPPI);
-    rcc8Graph->AddEdge(0,1,edge);
+    fail(rcc8Graph->GetVertex(2)->GetSegmentationImageIndex()!=2,
+	 "rcc8Graph->GetVertex(2)->GetSegmentationImageIndex()!=2");
+    fail(rcc8Graph->GetVertex(2)->GetObjectLabelInImage()!=3,
+	 "rcc8Graph->GetVertex(2)->GetObjectLabelInImgage()!=3");
+
+    // Testing the vertex iterators
+    int i=0;
+    VertexIteratorType v(rcc8Graph);
+    for(v.GoToBegin();!v.IsAtEnd();++v,i++)
+      {
+	fail(v.Get()->GetSegmentationImageIndex()!=i,
+	  "v.Get()->GetSegmentationImageIndex()!=i");
+	fail(v.Get()->GetObjectLabelInImage()!=(i+1),
+	 "v.Get()->GetSegmentationImageIndex()!=i");
+      }
+    
+    // // Testing the edge iterator
+//     rcc8Graph->AddEdge(0,1,otb::OTB_RCC8_NTPPI);
+//     rcc8Graph->AddEdge(1,2,otb::OTB_RCC8_EC);
+//     i = 0;
+//     EdgeIteratorType e = rcc8Graph->EdgeBegin();
+//     for(;e!=rcc8Graph->EdgeEnd();++e,i++)
+//       {
+// 	if(i==0)
+// 	  {
+// 	    fail(e.GetValue()!=otb::OTB_RCC8_NTPPI,
+// 		 "e.GetValue()!=otb::OTB_RCC8_NTPPI");
+// 	    fail(e.GetSourceIndex()!=0,
+// 		 "e.GetSourceIndex()!=0");
+// 	    fail(e.GetTargetIndex()!=1,
+// 		 "e.GetTargetIndex()!=1");
+// 	  }
+// 	else if(i==1)
+// 	  {
+// 	    fail(e.GetValue()!=otb::OTB_RCC8_EC,
+// 		 "e.GetValue()!=otb::OTB_RCC8_EC");
+// 	    fail(e.GetSourceIndex()!=1,
+// 		 "e.GetSourceIndex()!=1");
+// 	    fail(e.GetTargetIndex()!=2,
+// 		 "e.GetTargetIndex()!=2");
+// 	  }
+// 	else
+// 	  {
+// 	    fail(true,"Edge iterator out of bound."); 
+// 	  }
+//       }
   }
 catch( itk::ExceptionObject & err ) 
   { 
-- 
GitLab