diff --git a/Code/Common/otbPolygon.h b/Code/Common/otbPolygon.h
index 3c2faa615631bf2020db1694a5cbe8c030440fb2..d6cd9fabdcc192a24c89c4d2f7a7b148baf2d7e7 100644
--- a/Code/Common/otbPolygon.h
+++ b/Code/Common/otbPolygon.h
@@ -134,11 +134,16 @@ public:
   */
   virtual double GetLength() const;
 
+
+  void  AddVertex (const ContinuousIndexType &vertex);
+
 protected:
   /** Constructor */
   Polygon()
   {
     m_Epsilon = 0.000001;
+    m_Surface = -1.0;
+    surfaceValid = false;
   };
 
   /** Destructor */
@@ -147,12 +152,15 @@ protected:
   /**PrintSelf method */
   virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
 
+  virtual void ComputeSurface() const;
 
 private:
   Polygon(const Self&); //purposely not implemented
   void operator=(const Self&); //purposely not implemented
 
   double m_Epsilon;
+  mutable double m_Surface;
+  mutable bool surfaceValid;
 
 };
 }// End namespace otb
diff --git a/Code/Common/otbPolygon.txx b/Code/Common/otbPolygon.txx
index a6e73e9dd913f5f1f372e5f4f4c75881682e8bec..d92f679c80f73b79d9b0fd9d069178398c94f083 100644
--- a/Code/Common/otbPolygon.txx
+++ b/Code/Common/otbPolygon.txx
@@ -22,6 +22,16 @@ PURPOSE.  See the above copyright notices for more information.
 
 namespace otb
 {
+
+template<class TValue>
+void
+Polygon<TValue>
+::AddVertex(const ContinuousIndexType &vertex)
+{
+  Superclass::AddVertex(vertex);
+  surfaceValid=false;
+}
+
 /**
  * Check wether point is strictly inside the polygon.
  * \param point The point to check.
@@ -478,9 +488,9 @@ Polygon<TValue>
  * Surface computation (for non convex polygons as well)
  */
 template<class TValue>
-double
+void
 Polygon<TValue>
-::GetSurface() const
+::ComputeSurface() const
 {
   double m_Surface;
   m_Surface = 0.0;
@@ -515,9 +525,25 @@ Polygon<TValue>
     m_Surface = 0.0;
   }
 
+  surfaceValid = true;
+}
+
+/**
+ * Get surface
+ */
+template<class TValue>
+    double
+    Polygon<TValue>
+  ::GetSurface() const
+{
+  if (!surfaceValid)
+  {
+    ComputeSurface();
+  }
   return m_Surface;
 }
 
+
 /**
  * Lenght computation (difference with path is in the last addition)
  */