diff --git a/Code/IO/otbKmzProductWriter.h b/Code/IO/otbKmzProductWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..f3715adea691bfa9797f77552203b891c5f450f1
--- /dev/null
+++ b/Code/IO/otbKmzProductWriter.h
@@ -0,0 +1,272 @@
+/*=========================================================================
+
+  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 __otbKmzProductWriter_h
+#define __otbKmzProductWriter_h
+
+#include "itkProcessObject.h"
+#include "itkObjectFactory.h"
+
+//kmz creation
+#include "kml/engine/kmz_file.h"
+#include "kml/base/file.h"
+
+// Image Tiling
+#include "otbMultiChannelExtractROI.h"
+#include "otbImageFileWriter.h"
+#include "otbVectorRescaleIntensityImageFilter.h"
+#include <ogr_spatialref.h>
+#include "otbGenericRSTransform.h"
+#include "otbStreamingShrinkImageFilter.h"
+#include "itkCastImageFilter.h"
+
+// Possiblity to includes vectordatas necessary includes
+#include "otbVectorData.h"
+#include "otbVectorDataFileWriter.h"
+
+
+namespace otb
+{
+
+/** \class KmzProductWriter
+ * \brief This class generate a Kmz from one or several input
+ * images. The inputs must have a non empty metadata informations.
+ *
+ * This class writes kmz files, supported by GE. The input must have
+ * metadata 
+ * The size of the tiles can be set via the method
+ * SetTileSize(unsigned int) 
+ * 
+ *
+ * \ingroup IO
+ *
+ */
+template <class TInputImage>
+class ITK_EXPORT KmzProductWriter : public itk::ProcessObject
+{
+public:
+  /** Standard class typedefs. */
+  typedef KmzProductWriter                  Self;
+  typedef itk::ProcessObject                Superclass;
+  typedef itk::SmartPointer<Self>           Pointer;
+  typedef itk::SmartPointer<const Self>     ConstPointer;
+
+  /** Method for creation through the object factory. */
+  itkNewMacro(Self);
+
+  /** Run-time type information (and related methods). */
+  itkTypeMacro(KmzProductWriter, itk::ProcessObject);
+
+  /** Some convenient typedefs. */
+  typedef TInputImage                          InputImageType;
+  typedef typename InputImageType::InternalPixelType   InternalPixelType;
+  typedef typename InputImageType::SizeType    SizeType;
+  typedef typename InputImageType::IndexType   IndexType;
+  typedef unsigned char                        OutputPixelType;
+  typedef typename InputImageType::Pointer     InputImagePointer;
+  typedef typename InputImageType::RegionType  InputImageRegionType;
+  typedef typename InputImageType::PixelType   InputImagePixelType;
+
+  typedef VectorData<double,2>                    VectorDataType;
+  typedef typename VectorDataType::DataNodeType   DataNodeType;
+  typedef typename DataNodeType::PolygonType      PolygonType;
+  typedef typename PolygonType::VertexType        VertexType;
+  
+  typedef VectorDataFileWriter<VectorDataType>    VectorDataFileWriterType;
+  
+
+  /// Multi channels Extract ROI filter
+  typedef MultiChannelExtractROI<InternalPixelType, OutputPixelType> VectorImageExtractROIFilterType;
+
+  // Writer
+  typedef ImageFileWriter< VectorImage<OutputPixelType> >     VectorWriterType;
+
+  // Resampler
+  typedef StreamingShrinkImageFilter<InputImageType,InputImageType > StreamingShrinkImageFilterType;
+
+  // Intensity Rescale
+  typedef VectorRescaleIntensityImageFilter<InputImageType,
+					    InputImageType> VectorRescaleIntensityImageFilterType;
+
+  // Transformer
+  typedef GenericRSTransform<>           TransformType;
+  typedef TransformType::InputPointType  InputPointType;
+  typedef TransformType::OutputPointType OutputPointType;
+
+  // Cast Image Filter
+  typedef itk::CastImageFilter<InputImageType, VectorImage<OutputPixelType> > CastFilterType;
+
+
+  /** Dimension of input image. */
+  itkStaticConstMacro(InputImageDimension, unsigned int,
+                      InputImageType::ImageDimension);
+
+  virtual void SetInput( const InputImageType *image);
+  virtual void SetInput( unsigned int, const TInputImage * image);
+  const InputImageType * GetInput(void);
+  const InputImageType * GetInput(unsigned int idx);
+
+  itkSetStringMacro(Path);
+
+  /** Update Method */
+  virtual void Update()
+  {
+    this->Write();
+  }
+
+protected:
+  KmzProductWriter();
+  virtual ~KmzProductWriter();
+  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+  /**Method for Tiling the input image*/
+  virtual void Tiling();
+
+  /** Method for writing */
+  virtual void Write();
+
+private:
+  KmzProductWriter(const Self &); //purposely not implemented
+  void operator =(const Self&);  //purposely not implemented
+
+   /** Mehtod to initialize the variables*/
+   virtual void Initialize();
+
+  /**
+     * Close the root kml by adding the last flags and close the
+     * std::ofstream
+     */
+  void  CloseRootKML();
+
+//   /** Method to avoid code duplication*/
+//   /** call the method that generates the bounding box kml*/
+//   void BoundingBoxKmlProcess(double north, double south, double east, double west);
+
+   /** Method to generate the root kml*/
+   void RootKmlProcess(double north, double south, double east, double west);
+
+//   /** Add Roi to kmz*/
+//   void RegionOfInterestProcess();
+
+  /** KML root generate */
+  void GenerateKMLRoot(std::string title, double north, double south, double east, double west, bool extended);
+
+  /** KML generate  Filename - PathName - tile number - North - South - East - West */
+  void GenerateKML(std::string pathname, int depth, int x, int y, double north, double south, double east, double west);
+  void GenerateKMLExtended(std::string pathname,
+			   int depth,
+			   int x,
+                            int y,
+			   OutputPointType lowerLeft,
+                            OutputPointType lowerRight,
+			   OutputPointType upperRight,
+			   OutputPointType upperLeft);
+
+  /** KML with link generate */
+  void GenerateKMLWithLink(std::string pathname,
+                           int depth, int x, int y, int tileStartX, int tileStartY,
+			   double north, double south, double east, double west, double centerLong, double centerLat);
+  void GenerateKMLExtendedWithLink(std::string pathname,
+                                   int depth, int x, int y, int tileStartX, int tileStartY,
+                                   OutputPointType lowerLeft, OutputPointType lowerRight,
+                                   OutputPointType upperRight, OutputPointType upperLeft,
+                                   double centerLong, double centerLat);
+
+//   /** Method to create the bounding kml of the "iteration" th product */
+//   void GenerateBoundingKML(double north, double south,
+//                            double east,  double west);
+
+
+  /**
+    * Add a networkLink <NetworkLink> ....  </NetworkLink>
+    * to root kml (used to handle several image in the same kmz)
+    */
+  void AddNetworkLinkToRootKML(double north,
+                               double south,
+                               double east,
+                               double west,
+                               std::string directory,
+                               bool addRegion,
+                               unsigned int pos);
+
+  /**
+   * Add file to KMZ : return the number of error when writing the
+   * file in the kmz
+   */
+  virtual int  AddFileToKMZ(std::ostringstream&  absolutePath, std::ostringstream&   kmz_in_path);
+
+  /**Cut the image file name to built the directory name*/
+  std::string GetCuttenFileName(std::string description, unsigned int idx);
+
+  std::string          m_Path;
+  bool                 m_UseExtendMode;
+  InputImagePointer    m_VectorImage;
+  InputImagePointer    m_ResampleVectorImage;
+
+    // Extract ROI
+  typename VectorImageExtractROIFilterType::Pointer m_VectorImageExtractROIFilter;
+
+  // Writer
+  typename VectorWriterType::Pointer                m_VectorWriter;
+
+  // Resampler
+  typename StreamingShrinkImageFilterType::Pointer m_StreamingShrinkImageFilter;
+
+  // Rescale intensity
+  typename VectorRescaleIntensityImageFilterType::Pointer m_VectorRescaleIntensityImageFilter;
+
+  // Transformer
+  typename TransformType::Pointer                  m_Transform;
+
+  // VectorData Pointer Type for tileindex shapefile
+  typename VectorDataType::Pointer                 m_VectorDataIndexTile;
+  typename DataNodeType::Pointer                   m_Polygon;
+  typename DataNodeType::Pointer                   m_MultiPolygon;
+  typename DataNodeType::Pointer                   m_Folder;
+  
+  // Tile size
+  int                    m_TileSize;
+  int                    m_MaxDepth;
+  int                    m_CurrentDepth;
+  unsigned int           m_CurIdx;
+
+  // KMZ file
+  kmlengine::KmzFilePtr  m_KmzFile;
+  
+  // KMZ file name
+  std::ostringstream     m_KmzFileName;
+  
+  // the kml root ofstream
+  std::ofstream          m_RootKmlFile;
+  std::ofstream          m_TempRootKmlFile;
+
+    // File and path name
+  std::string            m_FileName;
+  std::string            m_CurrentImageName;
+
+  // Convenience string
+  std::string            m_KmzExtension;
+  std::string            m_KmlExtension;
+};
+
+} // end namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbKmzProductWriter.txx"
+#endif
+
+#endif 
diff --git a/Code/IO/otbKmzProductWriter.txx b/Code/IO/otbKmzProductWriter.txx
new file mode 100644
index 0000000000000000000000000000000000000000..0f730119a95315b54fc9d63b942dd37b500939ea
--- /dev/null
+++ b/Code/IO/otbKmzProductWriter.txx
@@ -0,0 +1,1281 @@
+/*=========================================================================
+
+  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 __otbKmzProductWriter_txx
+#define __otbKmzProductWriter_txx
+
+#include "otbKmzProductWriter.h"
+#include "itksys/SystemTools.hxx"
+
+#include "otbMetaDataKey.h"
+#include "otbVectorDataKeywordlist.h"
+#include "string.h"
+
+namespace otb
+{
+template <class TInputImage>
+KmzProductWriter<TInputImage>
+::KmzProductWriter():  m_TileSize(512),m_UseExtendMode(true)
+{
+  // Modify superclass default values, can be overridden by subclasses
+  this->SetNumberOfRequiredInputs(1);
+}
+
+template <class TInputImage>
+KmzProductWriter<TInputImage>
+::~KmzProductWriter()
+{
+  // Reset the boost::intrusive_ptr<KmzFile> :
+  // TODO : when upgrading boost > 1.42 use method release().
+  m_KmzFile = NULL;
+}
+
+/**
+ *
+ */
+template <class TInputImage>
+void 
+KmzProductWriter<TInputImage>
+::SetInput(const InputImageType *input)
+{
+  // Process object is not const-correct so the const_cast is required here
+  this->ProcessObject::SetNthInput(0, 
+                                   const_cast< InputImageType * >( input ) );
+}
+
+
+template <class TInputImage>
+void
+KmzProductWriter<TInputImage>
+::SetInput( unsigned int index, const TInputImage * image ) 
+{
+  // Process object is not const-correct so the const_cast is required here
+  this->ProcessObject::SetNthInput(index, 
+                                   const_cast< TInputImage *>( image ) );
+}
+
+/**
+ *
+ */
+template <class TInputImage>
+const typename KmzProductWriter<TInputImage>::InputImageType *
+KmzProductWriter<TInputImage>
+::GetInput(void) 
+{
+  if (this->GetNumberOfInputs() < 1)
+    {
+    return 0;
+    }
+  
+  return static_cast<const TInputImage * >
+    (this->ProcessObject::GetInput(0) );
+}
+  
+/**
+ *
+ */
+template <class TInputImage>
+const typename KmzProductWriter<TInputImage>::InputImageType *
+KmzProductWriter<TInputImage>
+::GetInput(unsigned int idx)
+{
+  return static_cast< const TInputImage * >
+    (this->ProcessObject::GetInput(idx));
+}
+
+template <class TInputImage>
+void
+KmzProductWriter<TInputImage>
+::Write()
+{
+  m_VectorImage = const_cast<TInputImage *>(this->GetInput());
+  std::cout <<"Input Information " << m_VectorImage->GetLargestPossibleRegion() << std::endl;
+  this->Initialize();
+  this->Tiling();
+}
+
+
+template <class TInputImage>
+void
+KmzProductWriter<TInputImage>
+::Initialize()
+{
+  m_FileName = itksys::SystemTools::GetFilenameWithoutExtension(m_Path);
+  m_Path = itksys::SystemTools::GetFilenamePath(m_Path);
+  m_CurrentImageName = this->GetCuttenFileName(m_FileName, 0);
+  
+  // Create the extension following the user choice
+  if (m_UseExtendMode)
+    {
+    m_KmzExtension = "xt.kmz";
+    m_KmlExtension = "xt.kml";
+    }
+  else
+    {
+    m_KmzExtension = ".kmz";
+    m_KmlExtension = ".kml";
+    }
+
+  // Create a kmz file
+  m_KmzFileName << m_Path << "/" << m_FileName << m_KmzExtension;
+  m_KmzFile = kmlengine::KmzFile::Create(m_KmzFileName.str().c_str());
+}
+
+
+template <class TInputImage>
+void
+KmzProductWriter<TInputImage>
+::Tiling()
+{
+  unsigned int numberOfChannel = m_VectorImage->GetNumberOfComponentsPerPixel();
+  unsigned int curIdx = 0;
+  
+  /** Image statistics*/
+  typename InputImageType::PixelType inMin(numberOfChannel), inMax(numberOfChannel), outMin(numberOfChannel), outMax(
+    numberOfChannel);
+  outMin.Fill(0);
+  outMax.Fill(255);
+
+  // Build wgs ref to compute long/lat
+  OGRSpatialReference oSRS;
+  oSRS.SetWellKnownGeogCS("WGS84");
+  char * wgsRef = NULL;
+  oSRS.exportToWkt(&wgsRef);
+
+  // Update image base information
+  m_VectorImage->UpdateOutputInformation();
+
+  // Get the image size
+  SizeType size;
+  size = m_VectorImage->GetLargestPossibleRegion().GetSize();
+
+  int sizeX = size[0];
+  int sizeY = size[1];
+
+  // Compute max depth
+  int maxDepth =
+    static_cast<int>(max(vcl_ceil(vcl_log(static_cast<float>(sizeX) / static_cast<float>(m_TileSize)) / vcl_log(2.0)),
+                         vcl_ceil(vcl_log(static_cast<float>(sizeY) / static_cast<float>(m_TileSize)) / vcl_log(2.0))));
+  m_MaxDepth = maxDepth;
+  m_CurIdx = 0;
+
+  // Compute nbTile
+  int nbTile = 0;
+
+  for (int i = 0; i <= maxDepth; i++)
+    {
+    int ratio = static_cast<int>(vcl_pow(2., (maxDepth - i)));
+    nbTile += (((sizeX / ratio) / m_TileSize) + 1)  * (((sizeY / ratio) / m_TileSize) + 1);
+    }
+
+  // Extract size & index
+  SizeType  extractSize;
+  IndexType extractIndex;
+
+  std::cout << "maxDepth " << maxDepth<< std::endl;
+  for (int depth = 0; depth <= maxDepth; depth++)
+    {
+
+    // update the attribute value Current Depth
+    m_CurrentDepth = depth;
+
+    // Resample image to the max Depth
+    int sampleRatioValue = static_cast<int>(vcl_pow(2., (maxDepth - depth)));
+
+    if (sampleRatioValue > 1)
+      {
+      m_StreamingShrinkImageFilter = StreamingShrinkImageFilterType::New();
+
+      m_StreamingShrinkImageFilter->SetShrinkFactor(sampleRatioValue);
+      m_StreamingShrinkImageFilter->SetInput(m_VectorImage);
+
+      m_VectorRescaleIntensityImageFilter = VectorRescaleIntensityImageFilterType::New();
+      m_VectorRescaleIntensityImageFilter->SetInput(m_StreamingShrinkImageFilter->GetOutput()); //m_ResampleVectorImage);
+      m_VectorRescaleIntensityImageFilter->SetOutputMinimum(outMin);
+      m_VectorRescaleIntensityImageFilter->SetOutputMaximum(outMax);
+
+      if (depth == 0)
+        {
+        m_VectorRescaleIntensityImageFilter->Update();
+        inMin = m_VectorRescaleIntensityImageFilter->GetInputMinimum();
+        inMax = m_VectorRescaleIntensityImageFilter->GetInputMaximum();
+        }
+      else
+        {
+        m_VectorRescaleIntensityImageFilter->SetInputMinimum(inMin);
+        m_VectorRescaleIntensityImageFilter->SetInputMaximum(inMax);
+        m_VectorRescaleIntensityImageFilter->SetAutomaticInputMinMaxComputation(false);
+        }
+
+      // New resample vector image
+      m_ResampleVectorImage = m_VectorRescaleIntensityImageFilter->GetOutput();
+      }
+    else
+      {
+      m_VectorRescaleIntensityImageFilter = VectorRescaleIntensityImageFilterType::New();
+      m_VectorRescaleIntensityImageFilter->SetInput(m_VectorImage);
+      m_VectorRescaleIntensityImageFilter->SetOutputMinimum(outMin);
+      m_VectorRescaleIntensityImageFilter->SetOutputMaximum(outMax);
+
+      m_VectorRescaleIntensityImageFilter->SetInputMinimum(inMin);
+      m_VectorRescaleIntensityImageFilter->SetInputMaximum(inMax);
+      m_VectorRescaleIntensityImageFilter->SetAutomaticInputMinMaxComputation(false);
+
+      m_ResampleVectorImage = m_VectorRescaleIntensityImageFilter->GetOutput();
+      }
+
+    m_ResampleVectorImage->UpdateOutputInformation();
+
+    // Get the image size
+    size = m_ResampleVectorImage->GetLargestPossibleRegion().GetSize();
+
+    sizeX = size[0];
+    sizeY = size[1];
+
+    int x = 0;
+    int y = 0;
+
+    // Tiling resample image
+    for (int tx = 0; tx < sizeX; tx += m_TileSize)
+      {
+      for (int ty = 0; ty < sizeY; ty += m_TileSize)
+        {
+        if ((tx + m_TileSize) >= sizeX)
+          {
+          extractIndex[0] = tx;
+          extractSize[0] = sizeX - tx;
+          }
+        else
+          {
+          extractIndex[0] = tx;
+          extractSize[0] = m_TileSize;
+          }
+
+        if ((ty + m_TileSize) >= sizeY)
+          {
+          extractIndex[1] = ty;
+          extractSize[1] = sizeY - ty;
+          }
+        else
+          {
+          extractIndex[1] = ty;
+          extractSize[1] = m_TileSize;
+          }
+
+        // Generate pathname
+        std::ostringstream path;
+        path << m_Path;
+	
+        ossimFilename cachingDir(path.str());
+        cachingDir.createDirectory();
+
+        // Generate Tile filename
+        std::ostringstream ossFileName;
+        ossFileName << m_Path;
+        ossFileName << "/";
+        ossFileName << y;
+        ossFileName << ".jpg";
+
+        std::cout <<"Writing the file "<< ossFileName.str() << std::endl;
+
+        // Extract ROI
+        m_VectorImageExtractROIFilter = VectorImageExtractROIFilterType::New();
+
+        // Set extract roi parameters
+        m_VectorImageExtractROIFilter->SetStartX(extractIndex[0]);
+        m_VectorImageExtractROIFilter->SetStartY(extractIndex[1]);
+        m_VectorImageExtractROIFilter->SetSizeX(extractSize[0]);
+        m_VectorImageExtractROIFilter->SetSizeY(extractSize[1]);
+
+        // Set Channel to extract
+        m_VectorImageExtractROIFilter->SetChannel(1);//m_ProductVector[m_CurrentProduct].m_Composition[0] + 1);
+	m_VectorImageExtractROIFilter->SetChannel(2);//m_ProductVector[m_CurrentProduct].m_Composition[1] + 1);
+	m_VectorImageExtractROIFilter->SetChannel(3);//m_ProductVector[m_CurrentProduct].m_Composition[2] + 1);
+
+        // Set extract roi input
+        m_VectorImageExtractROIFilter->SetInput(m_ResampleVectorImage);
+
+        // Configure writer
+        m_VectorWriter = VectorWriterType::New();
+        m_VectorWriter->SetFileName(ossFileName.str().c_str());
+        m_VectorWriter->SetInput(m_VectorImageExtractROIFilter->GetOutput());
+	m_VectorWriter->WriteGeomFileOn();
+        m_VectorWriter->Update();
+
+        /** TODO : Generate KML for this tile */
+        // Search Lat/Lon box
+        m_Transform = TransformType::New();
+        m_Transform->SetInputKeywordList(m_ResampleVectorImage->GetImageKeywordlist());
+        m_Transform->SetInputProjectionRef(m_VectorImage->GetProjectionRef());
+        m_Transform->SetOutputProjectionRef(wgsRef);
+        m_Transform->InstanciateTransform();
+
+        InputPointType  inputPoint;
+        OutputPointType outputPoint;
+        IndexType       indexTile;
+        SizeType        sizeTile, demiSizeTile;
+
+        sizeTile = extractSize;
+        demiSizeTile[0] = (sizeTile[0] / 2) - 1;
+        demiSizeTile[1] = (sizeTile[1] / 2) - 1;
+
+        // Compute North value
+        indexTile[0] = extractIndex[0] + demiSizeTile[0];
+        indexTile[1] = extractIndex[1];
+        m_ResampleVectorImage->TransformIndexToPhysicalPoint(indexTile, inputPoint);
+        outputPoint = m_Transform->TransformPoint(inputPoint);
+        double north = outputPoint[1];
+
+        // Compute South value
+        indexTile[0] = extractIndex[0] + demiSizeTile[0];
+        indexTile[1] = extractIndex[1] + sizeTile[1];
+        m_ResampleVectorImage->TransformIndexToPhysicalPoint(indexTile, inputPoint);
+        outputPoint = m_Transform->TransformPoint(inputPoint);
+        double south = outputPoint[1];
+
+        // Compute East value
+        indexTile[0] = extractIndex[0] + sizeTile[0];
+        indexTile[1] = extractIndex[1] + demiSizeTile[1];
+        m_ResampleVectorImage->TransformIndexToPhysicalPoint(indexTile, inputPoint);
+        outputPoint = m_Transform->TransformPoint(inputPoint);
+        double east = outputPoint[0];
+
+        // Compute West value
+        indexTile[0] = extractIndex[0];
+        indexTile[1] = extractIndex[1] + demiSizeTile[1];
+        m_ResampleVectorImage->TransformIndexToPhysicalPoint(indexTile, inputPoint);
+        outputPoint = m_Transform->TransformPoint(inputPoint);
+        double west = outputPoint[0];
+
+        // Compute center value (lat / long)
+        indexTile[0] = extractIndex[0] + demiSizeTile[1];
+        indexTile[1] = extractIndex[1] + demiSizeTile[1];
+        m_ResampleVectorImage->TransformIndexToPhysicalPoint(indexTile, inputPoint);
+        outputPoint = m_Transform->TransformPoint(inputPoint);
+        double centerLat = outputPoint[1];
+        double centerLong = outputPoint[0];
+
+        /** GX LAT LON **/
+        // Compute lower left corner
+        indexTile[0] = extractIndex[0];
+        indexTile[1] = extractIndex[1] + sizeTile[1];
+        m_ResampleVectorImage->TransformIndexToPhysicalPoint(indexTile, inputPoint);
+        outputPoint = m_Transform->TransformPoint(inputPoint);
+        OutputPointType lowerLeftCorner = outputPoint;
+	
+        // Compute lower right corner
+        indexTile[0] = extractIndex[0] + sizeTile[0];
+        indexTile[1] = extractIndex[1] + sizeTile[1];
+        m_ResampleVectorImage->TransformIndexToPhysicalPoint(indexTile, inputPoint);
+        outputPoint = m_Transform->TransformPoint(inputPoint);
+        OutputPointType lowerRightCorner = outputPoint;
+
+        // Compute upper right corner
+        indexTile[0] = extractIndex[0] + sizeTile[0];
+        indexTile[1] = extractIndex[1];
+        m_ResampleVectorImage->TransformIndexToPhysicalPoint(indexTile, inputPoint);
+        outputPoint = m_Transform->TransformPoint(inputPoint);
+        OutputPointType upperRightCorner = outputPoint;
+
+        // Compute upper left corner
+        indexTile[0] = extractIndex[0];
+        indexTile[1] = extractIndex[1];
+        m_ResampleVectorImage->TransformIndexToPhysicalPoint(indexTile, inputPoint);
+        outputPoint = m_Transform->TransformPoint(inputPoint);
+        OutputPointType upperLeftCorner = outputPoint;
+	
+        /** END GX LAT LON */
+
+	// Create KML - Filename - PathName - tile number - North - South - East - West
+	if (sampleRatioValue == 1)
+	  {
+	  if (!m_UseExtendMode) // Extended format
+	    this->GenerateKML(path.str(), depth, x, y, north, south, east, west);
+	  else 
+	    this->GenerateKMLExtended(path.str(), depth, 
+				      x, y, lowerLeftCorner, 
+				      lowerRightCorner, 
+				      upperRightCorner, upperLeftCorner);
+	  }
+	else
+	  {
+	  // Search tiles to link
+	  int tileXStart = extractIndex[0] / (m_TileSize / 2);
+	  int tileYStart = extractIndex[1] / (m_TileSize / 2);
+
+	  // Create KML with link
+	  if (!m_UseExtendMode)
+	    this->GenerateKMLWithLink(path.str(), depth, x, y, tileXStart, tileYStart,
+				      north, south, east, west, centerLong, centerLat);
+	  else
+	    this->GenerateKMLExtendedWithLink(
+	      path.str(), depth, x, y, tileXStart, tileYStart,
+	      lowerLeftCorner, lowerRightCorner, upperRightCorner, upperLeftCorner,
+	      centerLong, centerLat);
+	  }
+
+        if (depth == 0)
+          {
+          // Add the headers and the basic stuffs in the kml only once.
+          if (curIdx == 0)
+            {
+            this->RootKmlProcess(north, south, east, west);
+            }
+
+          // Add the bounding box kml
+          //this->BoundingBoxKmlProcess(north, south, east, west); :
+          //To Add After#########################
+          }
+
+        // Add the files to the kmz file
+        // Relative path to the root directory  in the kmz file
+        std::ostringstream jpg_in_kmz, kml_in_kmz;
+        jpg_in_kmz << m_CurrentImageName << "/" << depth << "/" << x << "/" << y << ".jpg";
+        kml_in_kmz << m_CurrentImageName << "/" << depth << "/" << x << "/" << y << m_KmlExtension;
+
+        // Absolute path where are stored the files
+        std::ostringstream jpg_absolute_path, kml_absolute_path;
+        jpg_absolute_path << m_Path << "/" << y << ".jpg";
+        kml_absolute_path << m_Path << "/" << y << m_KmlExtension;
+
+        //Add the files to the kmz
+        this->AddFileToKMZ(jpg_absolute_path, jpg_in_kmz);
+        this->AddFileToKMZ(kml_absolute_path, kml_in_kmz);
+
+        // Remove the unecessary files with stdio method :remove
+        if (remove(kml_absolute_path.str().c_str())  ||  remove(jpg_absolute_path.str().c_str()))
+          {
+          itkExceptionMacro(
+            << "Error while deleting the file" << kml_absolute_path.str() << "or file " << jpg_absolute_path.str());
+          }
+
+        y++;
+        }
+      x++;
+      y = 0;
+      }
+    }
+}
+
+
+/**
+*
+*/
+template <class TInputImage>
+int
+KmzProductWriter<TInputImage>
+::AddFileToKMZ(std::ostringstream& absolutePath, std::ostringstream& kmz_in_path)
+{
+  std::string absolute = absolutePath.str();
+  std::string relative = kmz_in_path.str();
+  std::string file_data;
+  int         errs = 0;
+  if (!kmlbase::File::ReadFileToString(absolute, &file_data))
+    {
+    itkExceptionMacro(<< "Error while reading file " << absolute);
+    }
+  else
+    {
+    m_KmzFile->AddFile(file_data, relative);
+    }
+
+  return errs;
+}
+
+
+/**
+ * Actually the root kml is not fully generated :
+ * It generates only the part till the network link
+ * In case of multiple inputs, other network liks are
+ * needed. See the method Add NetworkLinkToRootKML.
+ */
+template <class TInputImage>
+void
+KmzProductWriter<TInputImage>
+::GenerateKMLRoot(std::string title,
+		  double north,
+		  double south,
+		  double east,
+		  double west,
+		  bool extended)
+{
+  // Give a name to the root file
+  std::ostringstream kmlname;
+  kmlname << m_Path;
+  kmlname << "/";
+  kmlname << m_FileName;
+  kmlname << m_KmlExtension;
+  m_RootKmlFile.open(kmlname.str().c_str());
+  m_RootKmlFile << fixed << setprecision(6);
+
+  m_RootKmlFile << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl;
+  m_RootKmlFile << "<kml xmlns=\"http://www.opengis.net/kml/2.2\"" << std::endl;
+  m_RootKmlFile << " xmlns:gx=\"http://www.google.com/kml/ext/2.2\">" << std::endl;
+  m_RootKmlFile << "\t<Document>" << std::endl;
+  m_RootKmlFile << "\t\t<name>" << title << "</name>" << std::endl;
+  m_RootKmlFile << "\t\t<description></description>" << std::endl;
+  m_RootKmlFile << "\t\t<LookAt>" << std::endl;
+  m_RootKmlFile << "\t\t\t<longitude>" << (east + west) / 2. << "</longitude>" << std::endl;
+  m_RootKmlFile << "\t\t\t<latitude>" << (south + north) / 2. << "</latitude>" << std::endl;
+  m_RootKmlFile << "\t\t\t<altitude>35000</altitude>" << std::endl;
+  m_RootKmlFile << "\t\t\t<range>35000</range>" << std::endl;
+  m_RootKmlFile << "\t\t</LookAt>" << std::endl;
+}
+
+/**
+ */
+template <class TInputImage>
+void
+KmzProductWriter<TInputImage>
+::RootKmlProcess(double north, double south, double east, double west)
+{
+  bool extended = m_UseExtendMode;
+  this->GenerateKMLRoot(m_FileName, north, south, east, west, extended);
+
+  // Add the legend for this product if any
+  //this->AddCurrentProductLegends(0);
+
+  // Add the flag netwotk link for each input image
+  this->AddNetworkLinkToRootKML(north, south, east, west, m_CurrentImageName, true, 0);
+
+  // Root kml must be the first kml created
+  // Mutliple Inputs
+  for (unsigned int i = 1; i < 1; i++)
+    {
+    // Method to write a legend in the kmz
+    //this->AddCurrentProductLegends(i);
+
+    // Get the filename
+    //std::string fname  = this->GetInputDataDescription<FloatingVectorImageType>("InputImage", i);
+    std::string currentImageName = this->GetCuttenFileName(m_FileName, i);
+    
+    // Get the pĥysical coordinate of the center
+    SizeType tempSize = m_VectorImage->GetLargestPossibleRegion().GetSize();
+    InputPointType tempPoint, tempPointOrigin;
+    IndexType      tempIndex, tempIndexOrigin;
+    tempIndex[0] = tempSize[0];
+    tempIndex[1] = tempSize[1];
+    tempIndexOrigin.Fill(0);
+
+    m_VectorImage->TransformIndexToPhysicalPoint(tempIndex, tempPoint);
+    m_VectorImage->TransformIndexToPhysicalPoint(tempIndexOrigin,
+						 tempPointOrigin);
+
+    // Compute the transform
+    TransformType::Pointer tempTransform = TransformType::New();
+    tempTransform->SetInputKeywordList(m_VectorImage->GetImageKeywordlist());
+    tempTransform->SetInputProjectionRef(m_VectorImage->GetProjectionRef());
+    tempTransform->InstanciateTransform();
+
+    OutputPointType tempOutputPoint, tempOutputPointOrigin;
+    tempOutputPoint = tempTransform->TransformPoint(tempPoint);
+    tempOutputPointOrigin = tempTransform->TransformPoint(tempPointOrigin);
+
+    this->AddNetworkLinkToRootKML(tempOutputPointOrigin[1],
+				  tempOutputPoint[1], tempOutputPointOrigin[0],
+				  tempOutputPoint[0], currentImageName, false,
+				  i);
+    }
+
+  // Last thing to do is to close the root kml
+  this->CloseRootKML();
+
+  // Add the root kml in the kmz
+  std::ostringstream root_in_kmz;
+  root_in_kmz << m_FileName << m_KmlExtension;
+
+  std::ostringstream root_absolute_path;
+  root_absolute_path << m_Path << "/" << root_in_kmz.str();
+
+  // Add the root file in the kmz
+  this->AddFileToKMZ(root_absolute_path, root_in_kmz);
+
+  // Remove the root files with stdio method :remove
+  if (remove(root_absolute_path.str().c_str()) != 0)
+    {
+    itkExceptionMacro(<< "Error while deleting the file" << root_absolute_path.str());
+    }
+}
+
+/**
+ * Close the root kml
+ */
+template <class TInputImage>
+void
+KmzProductWriter<TInputImage>
+::CloseRootKML()
+{
+//   if (m_HasLogo)
+//     {
+//     RegionType logoReg = m_Logo->GetLargestPossibleRegion();
+//     SizeType   logoSize = logoReg.GetSize();
+//     double     lx = static_cast<double>(logoSize[0]);
+//     double     ly = static_cast<double>(logoSize[1]);
+//     int        sizey = 150;
+//     int        sizex = static_cast<int>((lx / ly * sizey));
+
+//     /** LOGO **/
+//     m_RootKmlFile << "\t\t<ScreenOverlay>" << std::endl;
+//     m_RootKmlFile << "\t\t\t<Icon>" << std::endl;
+//     m_RootKmlFile << "\t\t\t\t<href>logo.jpeg</href>" << std::endl;
+//     m_RootKmlFile << "\t\t\t</Icon>" << std::endl;
+//     m_RootKmlFile << "\t\t\t<name>Logo</name>" << std::endl;
+//     m_RootKmlFile << "\t\t\t<overlayXY x=\"1\" y=\"1\" xunits=\"fraction\" yunits=\"fraction\"/>" << std::endl;
+//     m_RootKmlFile << "\t\t\t<screenXY x=\"1\" y=\"1\" xunits=\"fraction\" yunits=\"fraction\"/>" << std::endl;
+//     m_RootKmlFile << "\t\t\t<size x=\"" << sizex << "\" y=\"" << sizey <<
+//     "\" xunits=\"pixels\" yunits=\"pixels\"/> " << std::endl;
+//     m_RootKmlFile << "\t\t</ScreenOverlay>" << std::endl;
+
+//     /** LOGO **/
+//     }
+
+  m_RootKmlFile << "\t</Document>" << std::endl;
+  m_RootKmlFile << "</kml>" << std::endl;
+  m_RootKmlFile.close();
+}
+
+
+/**
+ * Add A networkLink to the root kml
+ *
+ */
+template <class TInputImage>
+void
+KmzProductWriter<TInputImage>
+::AddNetworkLinkToRootKML(double north,
+			  double south,
+			  double east,
+			  double west,
+			  std::string directory,
+			  bool addRegion,
+			  unsigned int pos)
+{
+  m_RootKmlFile << "\t\t<Document>" << std::endl;
+  m_RootKmlFile << "\t\t\t<name>" << m_FileName<< "</name>" << std::endl;
+  //m_RootKmlFile << "\t\t\t<Description>" << m_ProductVector[pos].m_Description << "</Description>" << std::endl;
+  m_RootKmlFile << "\t\t\t<LookAt>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t<longitude>" << (east + west) / 2. << "</longitude>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t<latitude>" << (south + north) / 2. << "</latitude>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t<altitude>35000</altitude>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t<range>35000</range>" << std::endl;
+  m_RootKmlFile << "\t\t\t</LookAt>" << std::endl;
+
+  // Georeferenced Products
+  // Add network link
+  // If not geo add a ground Overlay with image
+  // as an icon
+//   if (this->IsProductHaveMetaData(pos))
+//     {
+  m_RootKmlFile << "\t\t\t<NetworkLink>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t<name>" << m_FileName<< "</name>" <<  std::endl;
+  m_RootKmlFile << "\t\t\t\t<open>1</open>" << std::endl;
+  m_RootKmlFile << "\t\t\t<Style>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t<ListStyle id=\"hideChildren\">" << std::endl;
+  m_RootKmlFile << "\t\t\t\t\t<listItemType>checkHideChildren</listItemType>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t</ListStyle>" << std::endl;
+  m_RootKmlFile << "\t\t\t</Style>" << std::endl;
+  if (addRegion)
+    {
+    m_RootKmlFile << "\t\t\t\t<Region>" << std::endl;
+    m_RootKmlFile << "\t\t\t\t\t<Lod>" << std::endl;
+    m_RootKmlFile << "\t\t\t\t\t\t<minLodPixels>" << m_TileSize / 2 << "</minLodPixels>" << std::endl;
+    /** If the last depth, put level of detail LOD to infinite (ie -1)*/
+    if (m_CurrentDepth == m_MaxDepth) 
+      m_RootKmlFile << "\t\t\t\t\t\t<maxLodPixels>-1</maxLodPixels>" << std::endl;
+    else 
+      m_RootKmlFile << "\t\t\t\t\t\t<maxLodPixels>" << m_TileSize * 4 << "</maxLodPixels>" << std::endl;
+    m_RootKmlFile << "\t\t\t\t\t</Lod>" << std::endl;
+    m_RootKmlFile << "\t\t\t\t\t<LatLonAltBox>" << std::endl;
+    m_RootKmlFile << "\t\t\t\t\t\t<north>" << north << "</north>" << std::endl;
+    m_RootKmlFile << "\t\t\t\t\t\t<south>" << south << "</south>" << std::endl;
+    m_RootKmlFile << "\t\t\t\t\t\t<east>" << east << "</east>" << std::endl;
+    m_RootKmlFile << "\t\t\t\t\t\t<west>" << west << "</west>" << std::endl;
+    m_RootKmlFile << "\t\t\t\t\t</LatLonAltBox>" << std::endl;
+    m_RootKmlFile << "\t\t\t\t</Region>" << std::endl;
+    }
+
+  m_RootKmlFile << "\t\t\t\t<Link>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t\t<href>" << directory << "/0/0/0" << m_KmlExtension << "</href>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t\t<viewRefreshMode>onRegion</viewRefreshMode>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t</Link>" << std::endl;
+  m_RootKmlFile << "\t\t\t</NetworkLink>" << std::endl;
+//    }
+//   else
+//     {
+//     m_RootKmlFile << "\t\t\t<GroundOverlay>" << std::endl;
+//     m_RootKmlFile << "\t\t\t\t<name>" << m_FileName<< "</name>" << std::endl;
+//     m_RootKmlFile << "\t\t\t\t<Icon>" << std::endl;
+//     m_RootKmlFile << "\t\t\t\t\t<href>" << directory << "/0.jpg" << "</href>" << std::endl;
+//     m_RootKmlFile << "\t\t\t\t</Icon>" << std::endl;
+
+//     if (!m_UseExtendMode)
+//       {
+//       m_RootKmlFile << "\t\t\t\t<LatLonBox>" << std::endl;
+//       m_RootKmlFile << "\t\t\t\t\t<north>" << north << "</north>" << std::endl;
+//       m_RootKmlFile << "\t\t\t\t\t<south>" << south << "</south>" << std::endl;
+//       m_RootKmlFile << "\t\t\t\t\t<east>" << east << "</east>" << std::endl;
+//       m_RootKmlFile << "\t\t\t\t\t<west>" << west << "</west>" << std::endl;
+//       m_RootKmlFile << "\t\t\t\t</LatLonBox>" << std::endl;
+//       }
+//     else
+//       {
+//       m_RootKmlFile << "\t\t\t<gx:LatLonQuad>" << std::endl;
+//       m_RootKmlFile << "\t\t\t\t<coordinates>" << std::endl;
+//       m_RootKmlFile << " " << m_LowerLeftCorner[0]  << "," << m_LowerLeftCorner[1];
+//       m_RootKmlFile << " " << m_LowerRightCorner[0] << "," << m_LowerRightCorner[1];
+//       m_RootKmlFile << " " << m_UpperRightCorner[0] << "," << m_UpperRightCorner[1];
+//       m_RootKmlFile << " " << m_UpperLeftCorner[0]  << "," << m_UpperRightCorner[1]  << std::endl;
+//       m_RootKmlFile << "\t\t\t\t</coordinates>" << std::endl;
+//       m_RootKmlFile << "\t\t\t</gx:LatLonQuad>" << std::endl;
+//       }
+//     m_RootKmlFile << "\t\t\t</GroundOverlay>" << std::endl;
+//     }
+
+  m_RootKmlFile << "\t\t\t<Folder>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t<name>The bounding box </name>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t<Style>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t\t<ListStyle id=\"hideChildren\">" << std::endl;
+  m_RootKmlFile << "\t\t\t\t\t\t<listItemType>checkHideChildren</listItemType>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t\t</ListStyle>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t</Style>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t<NetworkLink>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t<Region>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t\t<Lod>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t\t\t<minLodPixels>" << m_TileSize / 2 << "</minLodPixels>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t\t\t<maxLodPixels>-1</maxLodPixels>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t\t</Lod>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t</Region>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t<Link>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t\t<href>bounds/bound_" << pos << m_KmlExtension << "</href>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t\t<viewRefreshMode>onRegion</viewRefreshMode>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t</Link>" << std::endl;
+  m_RootKmlFile << "\t\t\t\t</NetworkLink>" << std::endl;
+  m_RootKmlFile << "\t\t\t</Folder>" << std::endl;
+
+  // Add a placemark with the images used as legend
+  // If any
+  //this->AddLegendToRootKml(north, south, east, west, pos);
+
+  m_RootKmlFile << "\t\t</Document>" << std::endl;
+}
+
+
+template <class TInputImage>
+void
+KmzProductWriter<TInputImage>
+::GenerateKMLExtended(std::string pathname, int depth, int x, int y,
+		      OutputPointType lowerLeft, OutputPointType lowerRight,
+		      OutputPointType upperRight, OutputPointType upperLeft)
+{
+  std::ostringstream kmlname;
+  kmlname << pathname;
+  kmlname << "/";
+  kmlname << y << "xt.kml";
+  std::ofstream fileTest(kmlname.str().c_str());
+
+  fileTest << fixed << setprecision(6);
+
+  fileTest << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl;
+  fileTest << "<kml xmlns=\"http://www.opengis.net/kml/2.2\"" << std::endl;
+  fileTest << " xmlns:gx=\"http://www.google.com/kml/ext/2.2\">" << std::endl;
+  fileTest << "\t<Document>" << std::endl;
+  fileTest << "\t\t<name>" << y << "xt.kml</name>" << std::endl;
+  fileTest << "\t\t<Region>" << std::endl;
+  fileTest << "\t\t\t<Lod>" << std::endl;
+  fileTest << "\t\t\t\t<minLodPixels>" << m_TileSize / 2 << "</minLodPixels>" << std::endl;
+  fileTest << "\t\t\t\t<maxLodPixels>-1</maxLodPixels>" << std::endl;
+  fileTest << "\t\t\t</Lod>" << std::endl;
+  fileTest << "\t\t\t<gx:LatLonQuad>" << std::endl;
+  fileTest << "\t\t\t\t<coordinates>" << std::endl;
+  fileTest << "\t\t\t\t\t" << lowerLeft[0]  << "," << lowerLeft[1];
+  fileTest << " " << lowerRight[0] << "," << lowerRight[1];
+  fileTest << " " << upperRight[0] << "," << upperRight[1];
+  fileTest << " " << upperLeft[0]  << "," << upperLeft[1]  << std::endl;
+  fileTest << "\t\t\t\t</coordinates>" << std::endl;
+  fileTest << "\t\t\t</gx:LatLonQuad>" << std::endl;
+  fileTest << "\t\t</Region>" << std::endl;
+  fileTest << "\t\t<GroundOverlay>" << std::endl;
+  fileTest << "\t\t\t<drawOrder>" << depth + (m_CurIdx * m_MaxDepth) << "</drawOrder>" << std::endl;
+  fileTest << "\t\t\t<Icon>" << std::endl;
+  fileTest << "\t\t\t\t<href>" << y << ".jpg" << "</href>" << std::endl;
+  fileTest << "\t\t\t</Icon>" << std::endl;
+  fileTest << "\t\t\t<gx:LatLonQuad>" << std::endl;
+  fileTest << "\t\t\t\t<coordinates>" << std::endl;
+  fileTest << "\t\t\t\t\t" << lowerLeft[0]  << "," << lowerLeft[1];
+  fileTest << " " << lowerRight[0] << "," << lowerRight[1];
+  fileTest << " " << upperRight[0] << "," << upperRight[1];
+  fileTest << " " << upperLeft[0]  << "," << upperLeft[1]  << std::endl;
+  fileTest << "\t\t\t\t</coordinates>" << std::endl;
+  fileTest << "\t\t\t</gx:LatLonQuad>" << std::endl;
+  fileTest << "\t\t</GroundOverlay>" << std::endl;
+  fileTest << "\t</Document>" << std::endl;
+  fileTest << "</kml>" << std::endl;
+
+  fileTest.close();
+}
+
+
+template <class TInputImage>
+void
+KmzProductWriter<TInputImage>
+::GenerateKML(std::string pathname, int depth, int x, int y, double north, double south, double east, double west)
+{
+  std::ostringstream kmlname;
+  kmlname << pathname;
+  kmlname << "/";
+  kmlname << y << ".kml";
+  std::ofstream fileTest(kmlname.str().c_str());
+
+  fileTest << fixed << setprecision(6);
+
+  fileTest << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl;
+  fileTest << "<kml xmlns=\"http://www.opengis.net/kml/2.2\"" << std::endl;
+  fileTest << " xmlns:gx=\"http://www.google.com/kml/ext/2.2\">" << std::endl;
+  fileTest << "\t<Document>" << std::endl;
+  fileTest << "\t\t<name>" << y << ".kml</name>" << std::endl;
+  fileTest << "\t\t<Region>" << std::endl;
+  fileTest << "\t\t\t<Lod>" << std::endl;
+  fileTest << "\t\t\t\t<minLodPixels>" << m_TileSize / 2 << "</minLodPixels>" << std::endl;
+  if (m_CurrentDepth == m_MaxDepth) fileTest << "\t\t\t\t<maxLodPixels>-1</maxLodPixels>" << std::endl;
+  else fileTest << "\t\t\t\t<maxLodPixels>" << m_TileSize * 4 << "</maxLodPixels>" << std::endl;
+  fileTest << "\t\t\t</Lod>" << std::endl;
+  fileTest << "\t\t\t<LatLonAltBox>" << std::endl;
+  fileTest << "\t\t\t\t<north>" << north << "</north>" << std::endl;
+  fileTest << "\t\t\t\t<south>" << south << "</south>" << std::endl;
+  fileTest << "\t\t\t\t<east>" << east << "</east>" << std::endl;
+  fileTest << "\t\t\t\t<west>" << west << "</west>" << std::endl;
+  fileTest << "\t\t\t</LatLonAltBox>" << std::endl;
+  fileTest << "\t\t</Region>" << std::endl;
+  fileTest << "\t\t<GroundOverlay>" << std::endl;
+  fileTest << "\t\t\t<drawOrder>" << depth + (m_CurIdx * m_MaxDepth) << "</drawOrder>" << std::endl;
+  fileTest << "\t\t\t<Icon>" << std::endl;
+  fileTest << "\t\t\t\t<href>" << y << ".jpg" << "</href>" << std::endl;
+  fileTest << "\t\t\t</Icon>" << std::endl;
+  fileTest << "\t\t\t<LatLonAltBox>" << std::endl;
+  fileTest << "\t\t\t\t<north>" << north << "</north>" << std::endl;
+  fileTest << "\t\t\t\t<south>" << south << "</south>" << std::endl;
+  fileTest << "\t\t\t\t<east>" << east << "</east>" << std::endl;
+  fileTest << "\t\t\t\t<west>" << west << "</west>" << std::endl;
+  fileTest << "\t\t\t</LatLonAltBox>" << std::endl;
+  fileTest << "\t\t</GroundOverlay>" << std::endl;
+  fileTest << "\t</Document>" << std::endl;
+  fileTest << "</kml>" << std::endl;
+
+  fileTest.close();
+}
+
+template <class TInputImage>
+void
+KmzProductWriter<TInputImage>
+::GenerateKMLExtendedWithLink(std::string pathname,
+			      int depth, int x, int y, int tileStartX, int tileStartY,
+			      OutputPointType lowerLeft, OutputPointType lowerRight,
+			      OutputPointType upperRight, OutputPointType upperLeft,
+			      double centerLong, double centerLat)
+{
+  std::ostringstream kmlname;
+  kmlname << pathname;
+  kmlname << "/";
+  kmlname << y << "xt.kml";
+  std::ofstream fileTest(kmlname.str().c_str());
+
+  fileTest << fixed << setprecision(6);
+
+  fileTest << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl;
+  fileTest << "<kml xmlns=\"http://www.opengis.net/kml/2.2\"" << std::endl;
+  fileTest << " xmlns:gx=\"http://www.google.com/kml/ext/2.2\">" << std::endl;
+  fileTest << "\t<Document>" << std::endl;
+  fileTest << "\t\t<name>" << y << "xt.kml</name>" << std::endl;
+  fileTest << "\t\t<Region>" << std::endl;
+  fileTest << "\t\t\t<Lod>" << std::endl;
+  fileTest << "\t\t\t\t<minLodPixels>" << m_TileSize / 2 << "</minLodPixels>" << std::endl;
+  fileTest << "\t\t\t\t<maxLodPixels>-1</maxLodPixels>" << std::endl;
+  fileTest << "\t\t\t</Lod>" << std::endl;
+  fileTest << "\t\t\t<gx:LatLonQuad>" << std::endl;
+  fileTest << "\t\t\t\t<coordinates>" << std::endl;
+  fileTest << "\t\t\t\t\t" << lowerLeft[0]  << "," << lowerLeft[1];
+  fileTest << " " << lowerRight[0] << "," << lowerRight[1];
+  fileTest << " " << upperRight[0] << "," << upperRight[1];
+  fileTest << " " << upperLeft[0]  << "," << upperLeft[1]  << std::endl;
+  fileTest << "\t\t\t\t</coordinates>" << std::endl;
+  fileTest << "\t\t\t</gx:LatLonQuad>" << std::endl;
+  fileTest << "\t\t</Region>" << std::endl;
+  fileTest << "\t\t<GroundOverlay>" << std::endl;
+  fileTest << "\t\t\t<drawOrder>" << depth + (m_CurIdx * m_MaxDepth) << "</drawOrder>" << std::endl;
+  fileTest << "\t\t\t<Icon>" << std::endl;
+  fileTest << "\t\t\t\t<href>" << y << ".jpg" << "</href>" << std::endl;
+  fileTest << "\t\t\t</Icon>" << std::endl;
+  fileTest << "\t\t\t<gx:LatLonQuad>" << std::endl;
+  fileTest << "\t\t\t\t<coordinates>" << std::endl;
+  fileTest << "\t\t\t\t\t" << lowerLeft[0]  << "," << lowerLeft[1];
+  fileTest << " " << lowerRight[0] << "," << lowerRight[1];
+  fileTest << " " << upperRight[0] << "," << upperRight[1];
+  fileTest << " " << upperLeft[0]  << "," << upperLeft[1]  << std::endl;
+  fileTest << "\t\t\t\t</coordinates>" << std::endl;
+  fileTest << "\t\t\t</gx:LatLonQuad>" << std::endl;
+  fileTest << "\t\t</GroundOverlay>" << std::endl;
+
+  /* Sous tuile 1 */
+  std::ostringstream fileTile1;
+  fileTile1 << "../../";
+  fileTile1 << depth + 1;
+  fileTile1 << "/";
+  fileTile1 << tileStartX;
+  fileTile1 << "/";
+  fileTile1 << tileStartY;
+
+  fileTest << "\t\t<NetworkLink>" << std::endl;
+  fileTest << "\t\t\t<name>" << fileTile1.str() << ".jpg</name>" << std::endl;
+  fileTest << "\t\t\t<Region>" << std::endl;
+  fileTest << "\t\t\t\t<Lod>" << std::endl;
+  fileTest << "\t\t\t\t\t<minLodPixels>" << m_TileSize / 2 << "</minLodPixels>" << std::endl;
+  fileTest << "\t\t\t\t\t<maxLodPixels>-1</maxLodPixels>" << std::endl;
+  fileTest << "\t\t\t\t</Lod>" << std::endl;
+  fileTest << "\t\t\t\t<gx:LatLonQuad>" << std::endl;
+  fileTest << "\t\t\t\t\t<coordinates>" << std::endl;
+  fileTest << "\t\t\t\t\t\t" << lowerLeft[0]  << "," << centerLat;
+  fileTest << " " << centerLong << "," << centerLat;
+  fileTest << " " << centerLong << "," << upperLeft[1];
+  fileTest << " " << upperLeft[0]  << "," << upperLeft[1]  << std::endl;
+  fileTest << "\t\t\t\t\t</coordinates>" << std::endl;
+  fileTest << "\t\t\t\t</gx:LatLonQuad>" << std::endl;
+  fileTest << "\t\t\t</Region>" << std::endl;
+  fileTest << "\t\t\t<Link>" << std::endl;
+  fileTest << "\t\t\t\t<href>" << fileTile1.str() << "xt.kml</href>" << std::endl;
+  fileTest << "\t\t\t\t<viewRefreshMode>onRegion</viewRefreshMode>" << std::endl;
+  fileTest << "\t\t\t\t<viewFormat/>" << std::endl;
+  fileTest << "\t\t\t</Link>" << std::endl;
+  fileTest << "\t\t</NetworkLink>" << std::endl;
+
+  /* Sous tuile 2 */
+  std::ostringstream fileTile2;
+  fileTile2 << "../../";
+  fileTile2 << depth + 1;
+  fileTile2 << "/";
+  fileTile2 << tileStartX + 1;
+  fileTile2 << "/";
+  fileTile2 << tileStartY;
+
+  fileTest << "\t\t<NetworkLink>" << std::endl;
+  fileTest << "\t\t\t<name>" << fileTile2.str() << ".jpg</name>" << std::endl;
+  fileTest << "\t\t\t<Region>" << std::endl;
+  fileTest << "\t\t\t<Lod>" << std::endl;
+  fileTest << "\t\t\t\t<minLodPixels>" << m_TileSize / 2 << "</minLodPixels>" << std::endl;
+  fileTest << "\t\t\t\t<maxLodPixels>-1</maxLodPixels>" << std::endl;
+  fileTest << "\t\t\t</Lod>" << std::endl;
+  fileTest << "\t\t\t\t<gx:LatLonQuad>" << std::endl;
+  fileTest << "\t\t\t\t\t<coordinates>" << std::endl;
+  fileTest << "\t\t\t\t\t\t" << centerLong  << "," << centerLat;
+  fileTest << " " << lowerRight[0] << "," << centerLat;
+  fileTest << " " << upperRight[0] << "," << upperRight[1];
+  fileTest << " " << centerLong << "," << upperLeft[1]  << std::endl;
+  fileTest << "\t\t\t\t\t</coordinates>" << std::endl;
+  fileTest << "\t\t\t\t</gx:LatLonQuad>" << std::endl;
+  fileTest << "\t\t\t</Region>" << std::endl;
+  fileTest << "\t\t\t<Link>" << std::endl;
+  fileTest << "\t\t\t\t<href>" << fileTile2.str() << "xt.kml</href>" << std::endl;
+  fileTest << "\t\t\t\t<viewRefreshMode>onRegion</viewRefreshMode>" << std::endl;
+  fileTest << "\t\t\t\t<viewFormat/>" << std::endl;
+  fileTest << "\t\t\t</Link>" << std::endl;
+  fileTest << "\t\t</NetworkLink>" << std::endl;
+
+  /* Sous tuile 3 */
+  std::ostringstream fileTile3;
+  fileTile3 << "../../";
+  fileTile3 << depth + 1;
+  fileTile3 << "/";
+  fileTile3 << tileStartX + 1;
+  fileTile3 << "/";
+  fileTile3 << tileStartY + 1;
+
+  fileTest << "\t\t<NetworkLink>" << std::endl;
+  fileTest << "\t\t\t<name>" << fileTile3.str() << ".jpg</name>" << std::endl;
+  fileTest << "\t\t\t<Region>" << std::endl;
+  fileTest << "\t\t\t\t<Lod>" << std::endl;
+  fileTest << "\t\t\t\t\t<minLodPixels>" << m_TileSize / 2 << "</minLodPixels>" << std::endl;
+  fileTest << "\t\t\t\t\t<maxLodPixels>-1</maxLodPixels>" << std::endl;
+  fileTest << "\t\t\t\t</Lod>" << std::endl;
+  fileTest << "\t\t\t\t<gx:LatLonQuad>" << std::endl;
+  fileTest << "\t\t\t\t\t<coordinates>" << std::endl;
+  fileTest << "\t\t\t\t\t\t" << centerLong  << "," << lowerLeft[1];
+  fileTest << " " << lowerRight[0] << "," << lowerRight[1];
+  fileTest << " " << upperRight[0] << "," << centerLat;
+  fileTest << " " << centerLong  << "," << centerLat  << std::endl;
+  fileTest << "\t\t\t\t\t</coordinates>" << std::endl;
+  fileTest << "\t\t\t\t</gx:LatLonQuad>" << std::endl;
+  fileTest << "\t\t\t</Region>" << std::endl;
+  fileTest << "\t\t\t<Link>" << std::endl;
+  fileTest << "\t\t\t\t<href>" << fileTile3.str() << "xt.kml</href>" << std::endl;
+  fileTest << "\t\t\t\t<viewRefreshMode>onRegion</viewRefreshMode>" << std::endl;
+  fileTest << "\t\t\t\t<viewFormat/>" << std::endl;
+  fileTest << "\t\t\t</Link>" << std::endl;
+  fileTest << "\t\t</NetworkLink>" << std::endl;
+
+  /* Sous tuile 4 */
+  std::ostringstream fileTile4;
+  fileTile4 << "../../";
+  fileTile4 << depth + 1;
+  fileTile4 << "/";
+  fileTile4 << tileStartX;
+  fileTile4 << "/";
+  fileTile4 << tileStartY + 1;
+
+  fileTest << "\t\t<NetworkLink>" << std::endl;
+  fileTest << "\t\t\t<name>" << fileTile4.str() << ".jpg</name>" << std::endl;
+  fileTest << "\t\t\t<Region>" << std::endl;
+  fileTest << "\t\t\t\t<Lod>" << std::endl;
+  fileTest << "\t\t\t\t\t<minLodPixels>" << m_TileSize / 2 << "</minLodPixels>" << std::endl;
+  fileTest << "\t\t\t\t\t<maxLodPixels>-1</maxLodPixels>" << std::endl;
+  fileTest << "\t\t\t\t</Lod>" << std::endl;
+  fileTest << "\t\t\t\t<gx:LatLonQuad>" << std::endl;
+  fileTest << "\t\t\t\t\t<coordinates>" << std::endl;
+  fileTest << "\t\t\t\t\t\t" << lowerLeft[0]  << "," << lowerLeft[1];
+  fileTest << "\t\t\t\t\t\t" << centerLong << "," << lowerRight[1];
+  fileTest << "\t\t\t\t\t\t" << centerLong << "," << centerLat;
+  fileTest << "\t\t\t\t\t\t" << upperLeft[0] << "," << centerLat  << std::endl;
+  fileTest << "\t\t\t\t\t</coordinates>" << std::endl;
+  fileTest << "\t\t\t\t</gx:LatLonQuad>" << std::endl;
+  fileTest << "\t\t\t</Region>" << std::endl;
+  fileTest << "\t\t\t<Link>" << std::endl;
+  fileTest << "\t\t\t\t<href>" << fileTile4.str() << "xt.kml</href>" << std::endl;
+  fileTest << "\t\t\t\t<viewRefreshMode>onRegion</viewRefreshMode>" << std::endl;
+  fileTest << "\t\t\t\t<viewFormat/>" << std::endl;
+  fileTest << "\t\t\t</Link>" << std::endl;
+  fileTest << "\t\t</NetworkLink>" << std::endl;
+
+  fileTest << "\t</Document>" << std::endl;
+  fileTest << "</kml>" << std::endl;
+  fileTest.close();
+
+}
+
+template <class TInputImage>
+void
+KmzProductWriter<TInputImage>
+::GenerateKMLWithLink(std::string pathname,
+		      int depth, int x, int y, int tileStartX, int tileStartY,
+		      double north, double south, double east, double west, double centerLong, double centerLat)
+{
+  std::ostringstream kmlname;
+  kmlname << pathname;
+  kmlname << "/";
+  kmlname << y << ".kml";
+  std::ofstream fileTest(kmlname.str().c_str());
+
+  fileTest << fixed << setprecision(6);
+
+  fileTest << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl;
+  fileTest << "<kml xmlns=\"http://www.opengis.net/kml/2.2\"" << std::endl;
+  fileTest << " xmlns:gx=\"http://www.google.com/kml/ext/2.2\">" << std::endl;
+  fileTest << "\t<Document>" << std::endl;
+  fileTest << "\t\t<name>" << y << ".kml</name>" << std::endl;
+  fileTest << "\t\t<Region>" << std::endl;
+  fileTest << "\t\t\t<Lod>" << std::endl;
+  fileTest << "\t\t\t\t<minLodPixels>" << m_TileSize / 2 << "</minLodPixels>" << std::endl;
+  if (m_CurrentDepth == m_MaxDepth) 
+    fileTest << "\t\t\t\t<maxLodPixels>-1</maxLodPixels>" << std::endl;
+  else 
+    fileTest << "\t\t\t\t<maxLodPixels>" << m_TileSize * 2 << "</maxLodPixels>" << std::endl;
+  fileTest << "\t\t\t</Lod>" << std::endl;
+  fileTest << "\t\t\t<LatLonAltBox>" << std::endl;
+  fileTest << "\t\t\t\t<north>" << north << "</north>" << std::endl;
+  fileTest << "\t\t\t\t<south>" << south << "</south>" << std::endl;
+  fileTest << "\t\t\t\t<east>" << east << "</east>" << std::endl;
+  fileTest << "\t\t\t\t<west>" << west << "</west>" << std::endl;
+  fileTest << "\t\t\t</LatLonAltBox>" << std::endl;
+  fileTest << "\t\t</Region>" << std::endl;
+  fileTest << "\t\t<GroundOverlay>" << std::endl;
+  fileTest << "\t\t\t<drawOrder>" << depth + (m_CurIdx * m_MaxDepth) << "</drawOrder>" << std::endl;
+  fileTest << "\t\t\t<Icon>" << std::endl;
+  fileTest << "\t\t\t\t<href>" << y << ".jpg" << "</href>" << std::endl;
+  fileTest << "\t\t\t</Icon>" << std::endl;
+  fileTest << "\t\t\t<LatLonAltBox>" << std::endl;
+  fileTest << "\t\t\t\t<north>" << north << "</north>" << std::endl;
+  fileTest << "\t\t\t\t<south>" << south << "</south>" << std::endl;
+  fileTest << "\t\t\t\t<east>" << east << "</east>" << std::endl;
+  fileTest << "\t\t\t\t<west>" << west << "</west>" << std::endl;
+  fileTest << "\t\t\t</LatLonAltBox>" << std::endl;
+  fileTest << "\t\t</GroundOverlay>" << std::endl;
+
+  /* Sous tuile 1 */
+  std::ostringstream fileTile1;
+  fileTile1 << "../../";
+  fileTile1 << depth + 1;
+  fileTile1 << "/";
+  fileTile1 << tileStartX;
+  fileTile1 << "/";
+  fileTile1 << tileStartY;
+
+  fileTest << "\t\t<NetworkLink>" << std::endl;
+  fileTest << "\t\t\t<name>" << fileTile1.str() << ".jpg</name>" << std::endl;
+  fileTest << "\t\t\t<Region>" << std::endl;
+  fileTest << "\t\t\t\t<Lod>" << std::endl;
+  fileTest << "\t\t\t\t\t<minLodPixels>" << m_TileSize / 2 << "</minLodPixels>" << std::endl;
+  if (m_CurrentDepth == m_MaxDepth) fileTest << "\t\t\t\t<maxLodPixels>-1</maxLodPixels>" << std::endl;
+  else fileTest << "\t\t\t\t<maxLodPixels>" << m_TileSize * 2 << "</maxLodPixels>" << std::endl;
+  fileTest << "\t\t\t\t</Lod>" << std::endl;
+  fileTest << "\t\t\t\t<LatLonAltBox>" << std::endl;
+  fileTest << "\t\t\t\t\t<north>" << north << "</north>" << std::endl;
+  fileTest << "\t\t\t\t\t<south>" << centerLat << "</south>" << std::endl;
+  fileTest << "\t\t\t\t\t<east>" << centerLong << "</east>" << std::endl;
+  fileTest << "\t\t\t\t\t<west>" << west << "</west>" << std::endl;
+  fileTest << "\t\t\t\t</LatLonAltBox>" << std::endl;
+  fileTest << "\t\t\t</Region>" << std::endl;
+  fileTest << "\t\t\t<Link>" << std::endl;
+  fileTest << "\t\t\t\t<href>" << fileTile1.str() << ".kml</href>" << std::endl;
+  fileTest << "\t\t\t\t<viewRefreshMode>onRegion</viewRefreshMode>" << std::endl;
+  fileTest << "\t\t\t\t<viewFormat/>" << std::endl;
+  fileTest << "\t\t\t</Link>" << std::endl;
+  fileTest << "\t\t</NetworkLink>" << std::endl;
+
+  /* Sous tuile 2 */
+  std::ostringstream fileTile2;
+  fileTile2 << "../../";
+  fileTile2 << depth + 1;
+  fileTile2 << "/";
+  fileTile2 << tileStartX + 1;
+  fileTile2 << "/";
+  fileTile2 << tileStartY;
+
+  fileTest << "\t\t<NetworkLink>" << std::endl;
+  fileTest << "\t\t\t<name>" << fileTile2.str() << ".jpg</name>" << std::endl;
+  fileTest << "\t\t\t<Region>" << std::endl;
+  fileTest << "\t\t\t\t<Lod>" << std::endl;
+  fileTest << "\t\t\t\t\t<minLodPixels>" << m_TileSize / 2 << "</minLodPixels>" << std::endl;
+  if (m_CurrentDepth == m_MaxDepth) fileTest << "\t\t\t\t<maxLodPixels>-1</maxLodPixels>" << std::endl;
+  else fileTest << "\t\t\t\t<maxLodPixels>" << m_TileSize * 4 << "</maxLodPixels>" << std::endl;
+  fileTest << "\t\t\t\t</Lod>" << std::endl;
+  fileTest << "\t\t\t\t<LatLonAltBox>" << std::endl;
+  fileTest << "\t\t\t\t\t<north>" << north << "</north>" << std::endl;
+  fileTest << "\t\t\t\t\t<south>" << centerLat << "</south>" << std::endl;
+  fileTest << "\t\t\t\t\t<east>" << east << "</east>" << std::endl;
+  fileTest << "\t\t\t\t\t<west>" << centerLong << "</west>" << std::endl;
+  fileTest << "\t\t\t\t</LatLonAltBox>" << std::endl;
+  fileTest << "\t\t\t</Region>" << std::endl;
+  fileTest << "\t\t\t<Link>" << std::endl;
+  fileTest << "\t\t\t\t<href>" << fileTile2.str() << ".kml</href>" << std::endl;
+  fileTest << "\t\t\t\t<viewRefreshMode>onRegion</viewRefreshMode>" << std::endl;
+  fileTest << "\t\t\t\t<viewFormat/>" << std::endl;
+  fileTest << "\t\t\t</Link>" << std::endl;
+  fileTest << "\t\t</NetworkLink>" << std::endl;
+
+  /* Sous tuile 3 */
+  std::ostringstream fileTile3;
+  fileTile3 << "../../";
+  fileTile3 << depth + 1;
+  fileTile3 << "/";
+  fileTile3 << tileStartX + 1;
+  fileTile3 << "/";
+  fileTile3 << tileStartY + 1;
+
+  fileTest << "\t\t<NetworkLink>" << std::endl;
+  fileTest << "\t\t\t<name>" << fileTile3.str() << ".jpg</name>" << std::endl;
+  fileTest << "\t\t\t<Region>" << std::endl;
+  fileTest << "\t\t\t\t<Lod>" << std::endl;
+  fileTest << "\t\t\t\t\t<minLodPixels>" << m_TileSize / 2 << "</minLodPixels>" << std::endl;
+  if (m_CurrentDepth == m_MaxDepth) fileTest << "\t\t\t\t<maxLodPixels>-1</maxLodPixels>" << std::endl;
+  else fileTest << "\t\t\t\t<maxLodPixels>" << m_TileSize * 4 << "</maxLodPixels>" << std::endl;
+  fileTest << "\t\t\t\t</Lod>" << std::endl;
+  fileTest << "\t\t\t\t<LatLonAltBox>" << std::endl;
+  fileTest << "\t\t\t\t\t<north>" << centerLat << "</north>" << std::endl;
+  fileTest << "\t\t\t\t\t<south>" << south << "</south>" << std::endl;
+  fileTest << "\t\t\t\t\t<east>" << east << "</east>" << std::endl;
+  fileTest << "\t\t\t\t\t<west>" << centerLong << "</west>" << std::endl;
+  fileTest << "\t\t\t\t</LatLonAltBox>" << std::endl;
+  fileTest << "\t\t\t</Region>" << std::endl;
+  fileTest << "\t\t\t<Link>" << std::endl;
+  fileTest << "\t\t\t\t<href>" << fileTile3.str() << ".kml</href>" << std::endl;
+  fileTest << "\t\t\t\t<viewRefreshMode>onRegion</viewRefreshMode>" << std::endl;
+  fileTest << "\t\t\t\t<viewFormat/>" << std::endl;
+  fileTest << "\t\t\t</Link>" << std::endl;
+  fileTest << "\t\t</NetworkLink>" << std::endl;
+
+  /* Sous tuile 4 */
+  std::ostringstream fileTile4;
+  fileTile4 << "../../";
+  fileTile4 << depth + 1;
+  fileTile4 << "/";
+  fileTile4 << tileStartX;
+  fileTile4 << "/";
+  fileTile4 << tileStartY + 1;
+
+  fileTest << "\t\t<NetworkLink>" << std::endl;
+  fileTest << "\t\t\t<name>" << fileTile4.str() << ".jpg</name>" << std::endl;
+  fileTest << "\t\t\t<Region>" << std::endl;
+  fileTest << "\t\t\t\t<Lod>" << std::endl;
+  fileTest << "\t\t\t\t\t<minLodPixels>" << m_TileSize / 2 << "</minLodPixels>" << std::endl;
+  if (m_CurrentDepth == m_MaxDepth) fileTest << "\t\t\t\t<maxLodPixels>-1</maxLodPixels>" << std::endl;
+  else fileTest << "\t\t\t\t<maxLodPixels>" << m_TileSize * 4 << "</maxLodPixels>" << std::endl;
+
+  fileTest << "\t\t\t\t</Lod>" << std::endl;
+  fileTest << "\t\t\t\t<LatLonAltBox>" << std::endl;
+  fileTest << "\t\t\t\t\t<north>" << centerLat << "</north>" << std::endl;
+  fileTest << "\t\t\t\t\t<south>" << south << "</south>" << std::endl;
+  fileTest << "\t\t\t\t\t<east>" << centerLong << "</east>" << std::endl;
+  fileTest << "\t\t\t\t\t<west>" << west << "</west>" << std::endl;
+  fileTest << "\t\t\t\t</LatLonAltBox>" << std::endl;
+  fileTest << "\t\t\t</Region>" << std::endl;
+  fileTest << "\t\t\t<Link>" << std::endl;
+  fileTest << "\t\t\t\t<href>" << fileTile4.str() << ".kml</href>" << std::endl;
+  fileTest << "\t\t\t\t<viewRefreshMode>onRegion</viewRefreshMode>" << std::endl;
+  fileTest << "\t\t\t\t<viewFormat/>" << std::endl;
+  fileTest << "\t\t\t</Link>" << std::endl;
+  fileTest << "\t\t</NetworkLink>" << std::endl;
+
+  fileTest << "\t</Document>" << std::endl;
+  fileTest << "</kml>" << std::endl;
+  fileTest.close();
+
+}
+
+
+/**
+ */
+template <class TInputImage>
+std::string
+KmzProductWriter<TInputImage>
+::GetCuttenFileName(std::string description, unsigned int idx)
+{
+  std::string currentImageName;
+  std::string tempName;
+  
+  itk::OStringStream oss;
+  oss << "tiles_" << idx;
+  tempName = oss.str();
+  
+  // Replace all the blanks in the string
+  unsigned int i = 0;
+  while (i < tempName.length())
+    {
+    if (tempName[i] != ' ') currentImageName += tempName[i];
+    i++;
+    }
+
+  return currentImageName;
+}
+
+template <class TInputImage>
+void
+KmzProductWriter<TInputImage>
+::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  // Call the superclass implementation
+  Superclass::PrintSelf(os, indent);
+}
+
+}
+#endif
diff --git a/Examples/IO/CMakeLists.txt b/Examples/IO/CMakeLists.txt
index 7a2c37ad137acfc576157a7fc605cea1e72587da..ea258ee64b75fc75780bf68a52848ae7403605a6 100644
--- a/Examples/IO/CMakeLists.txt
+++ b/Examples/IO/CMakeLists.txt
@@ -117,6 +117,9 @@ ENDIF( OTB_USE_CURL )
 #ADD_EXECUTABLE(TransformReadWrite TransformReadWrite.cxx )
 #TARGET_LINK_LIBRARIES(TransformReadWrite)
 
+ADD_EXECUTABLE(ImageToKmzChain ImageToKmzChain.cxx)
+TARGET_LINK_LIBRARIES(ImageToKmzChain OTBIO)
+
 IF( NOT OTB_DISABLE_CXX_TESTING AND BUILD_TESTING )
 
 
@@ -166,6 +169,42 @@ ADD_TEST(ioTeDEMToImageGeneratorTest ${EXE_TESTS1}
           ${INPUTDATA}/DEM_srtm
          )
 
+# Testing the chain of creating a kmz from 
+# a non georeferenced image
+ADD_TEST(ioImageToKmzChain ${EXE_TESTS1}
+         #--compare-image ${EPSILON_5}  ${BASELINE}/DEMToImageGenerator.tif
+         #                      ${TEMP}/DEMToImageGenerator.tif
+         ImageToKmzChain
+         ${DATA}/Haiti1.jpeg
+         ${TEMP}/ioTeHaitiKmzProduct.kmz
+         1980.000000 1986.000000 -72.351257 18.555075 0.000000 
+         1963.000000 1944.000000 -72.352051 18.556946 0.000000
+         2078.000000 1566.000000 -72.346130 18.574358 0.000000
+         2154.000000 1430.000000 -72.342377 18.580441 0.000000
+         2432.000000 1408.000000 -72.328964 18.581335 0.000000
+         2558.000000 934.000000 -72.322571 18.602974 0.000000
+         3492.000000 1397.000000 -72.278343 18.580887 0.000000
+         2890.000000 1439.000000 -72.306908 18.579464 0.000000
+         2098.000000 2469.000000 -72.345741 18.532839 0.000000
+         1941.000000 2473.000000 -72.353317 18.532595 0.00000 
+         1644.000000 2409.000000 -72.367691 18.535810 0.000000
+         1440.000000 2448.000000 -72.377457 18.534243 0.000000
+         687.000000 2005.000000 -72.413315 18.554974 0.000000
+         741.000000 2366.000000 -72.410934 18.538496 0.000000
+         855.000000 2802.000000 -72.405739 18.518456 0.000000
+         1936.000000 2855.000000 -72.353920 18.515240 0.000000
+         3338.000000 2824.000000 -72.286240 18.515160 0.000000
+         3715.000000 1772.000000 -72.267570 18.563681 0.000000
+         3676.000000 1580.000000 -72.269203 18.572529 0.000000
+         3395.000000 931.000000 -72.282402 18.602425 0.000000
+         3426.000000 856.000000 -72.280792 18.605862 0.000000
+         2822.000000 707.000000 -72.309692 18.613203 0.000000
+         1891.000000 360.000000 -72.354301 18.629776 0.000000
+         3989.000000 2639.000000 -72.255020 18.523664 0.000000
+         417.000000 2317.000000 -72.426552 18.540876 0.000000
+         )
+       
+
 IF( OTB_USE_CURL )
 ADD_TEST(ioTeTileMapImageIOExampleTest ${EXE_TESTS2}
 --compare-image ${HIGHTOL}  ${BASELINE}/openStreetMap.png
@@ -240,4 +279,6 @@ ENDIF(ITK_USE_REVIEW)
 ENDIF(OTB_USE_LIBLAS)
 
 
+
+
 ENDIF( NOT OTB_DISABLE_CXX_TESTING AND BUILD_TESTING )
diff --git a/Examples/IO/ImageToKmzChain.cxx b/Examples/IO/ImageToKmzChain.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..909aaf6efcb9161d6bd9b10ab43c8fda6a2b227d
--- /dev/null
+++ b/Examples/IO/ImageToKmzChain.cxx
@@ -0,0 +1,162 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+
+// Software Guide : BeginLatex
+//
+// This example demonstrates the use of the
+// \doxygen{otb}{KmzProductWriter}. This filter is intended to
+// produce Kmz file (Google Earth Readable). In this example we will
+// use a file with no meta-data, use the
+// \doxygen{otb}{GGCPToRPCSensorModelImageFilter} in order to 
+// approximate a rpc model, and then use our filter to produce a kmz
+// file.
+// Note that the \doxygen{otb}{KmzProductWriter} can only process
+// inputs with a non empty keyword list.
+//
+// The first step toward the use of these filters is to include the
+// proper header files: the one for the rpc sensor estimation filter and
+// the one defining the procedure for creating kmz files.
+//
+// Software Guide : EndLatex
+
+#include "otbMacro.h"
+#include "otbVectorImage.h"
+#include "otbImageFileReader.h"
+
+// Software Guide : BeginCodeSnippet
+#include "otbKmzProductWriter.h"
+#include "otbGCPsToRPCSensorModelImageFilter.h"
+// Software Guide : EndCodeSnippet
+//
+
+int main(int argc, char* argv[])
+{
+
+  if (argc < 3)
+    {
+    std::cerr << "Usage: " << argv[0] << " infname outfname kmzFileName a1x a1y b1x b1y b1z ... aNx aNy aNz bNx bNy bNz" << std::endl;
+    return EXIT_FAILURE;
+    }
+  else if ((argc - 3) % 5 != 0)
+    {
+    std::cerr << "Inconsistent GCPs description!" << std::endl;
+    return EXIT_FAILURE;
+    }
+
+  
+// Software Guide : BeginLatex
+//
+// We will start by defining the types for the image and the image file
+// reader. 
+//
+// Software Guide : EndLatex
+// Software Guide : BeginCodeSnippet
+  typedef otb::VectorImage<float, 2>                      ImageType;
+  typedef otb::ImageFileReader<ImageType>                 ReaderType;
+
+  ReaderType::Pointer reader = ReaderType::New();
+  reader->SetFileName(argv[1]);
+// Software Guide : EndCodeSnippet
+
+// Software Guide : BeginLatex
+//
+// We can now proceed to declare the type for the rpc sensor model
+// estimation filter. The class \doxygen{otb}{GGCPToRPCSensorModelImageFilter} is
+// templated over the input image type. 
+//
+// Software Guide : EndLatex
+
+// Software Guide : BeginCodeSnippet
+  typedef otb::GCPsToRPCSensorModelImageFilter<ImageType> GCPsToSensorModelFilterType;
+  typedef GCPsToSensorModelFilterType::Point2DType        Point2DType;
+  typedef GCPsToSensorModelFilterType::Point3DType        Point3DType;
+
+  GCPsToSensorModelFilterType::Pointer rpcEstimator = GCPsToSensorModelFilterType::New();
+  rpcEstimator->SetInput(reader->GetOutput());
+// Software Guide : EndCodeSnippet
+
+  unsigned int nbGCPs = (argc - 3) / 5;
+
+  std::cout << "Receiving " << nbGCPs << " from command line." << std::endl;
+
+  for (unsigned int gcpId = 0; gcpId < nbGCPs; ++gcpId)
+    {
+// Software Guide : BeginLatex
+//
+// Here, we set all the Ground Control Points associated to the image
+// indexes. This is the entry of the rpc sensor model
+// estimator. Everytime a GCP is added, the output image information
+// or its keywordlist is updated. In general, a dozen of GCPs are
+// needed to estimate an accurate sensor model. The points are added
+// via the method AddGCP(PointType2D, PointType3D). The outpput image
+// obtained have the needed meta-data informations for the rest of the
+// process.
+//
+// Software Guide : EndLatex
+
+// Software Guide : BeginCodeSnippet
+    Point2DType sensorPoint;
+    sensorPoint[0] = atof(argv[3 + gcpId * 5]);
+    sensorPoint[1] = atof(argv[4 + gcpId * 5]);
+
+    Point3DType geoPoint;
+    geoPoint[0] = atof(argv[5 + 5 * gcpId]);
+    geoPoint[1] = atof(argv[6 + 5 * gcpId]);
+    geoPoint[2] = atof(argv[7 + 5 * gcpId]);
+
+    rpcEstimator->AddGCP(sensorPoint, geoPoint);
+// Software Guide : EndCodeSnippet
+
+    std::cout << "Adding GCP sensor: " << sensorPoint << " <-> geo: " << geoPoint << std::endl;
+    }
+
+  rpcEstimator->GetOutput()->UpdateOutputInformation();
+  std::cout << "Residual ground error: " << rpcEstimator->GetRMSGroundError() << std::endl;
+
+  
+// Software Guide : BeginLatex
+//
+// The last step of the chain, is to export the image to a Google 
+// Earth understandable format using the KmzProductWriter. Note that 
+// the writer can associate legend  via the method
+// AddLegend(std::string description,ImageType * legend) and a logo  
+// SetLogo(ImageType*) to the kmz. 
+//
+// Software Guide : EndLatex
+
+// Software Guide : BeginCodeSnippet
+  typedef otb::KmzProductWriter<ImageType>     KmzProductWriterType;
+  KmzProductWriterType::Pointer    kmzWriter  = KmzProductWriterType::New();
+// Software Guide : EndCodeSnippet
+
+// Software Guide : BeginLatex
+//
+// Finally, we trigger the kmz writting by calling the \code{Update()}
+// method on the writer. 
+//
+// Software Guide : EndLatex
+
+// Software Guide : BeginCodeSnippet
+  kmzWriter->SetInput(rpcEstimator->GetOutput());
+  kmzWriter->SetPath(argv[2]);
+  
+  kmzWriter->Update();
+// Software Guide : EndCodeSnippet
+
+  return EXIT_SUCCESS;
+}
diff --git a/Examples/IO/otbIOExamplesTests1.cxx b/Examples/IO/otbIOExamplesTests1.cxx
index 46e9ff85ea4807109391cdcdc5a66caa526b1bcc..e076a563cd7e9db6bc7801a40a31cc7049cd94a4 100644
--- a/Examples/IO/otbIOExamplesTests1.cxx
+++ b/Examples/IO/otbIOExamplesTests1.cxx
@@ -28,6 +28,8 @@ void RegisterTests()
 {
   REGISTER_TEST(ExtractROITest);
   REGISTER_TEST(DEMToImageGeneratorTest);
+  REGISTER_TEST(ImageToKmzChain);
+  
 }
 
 #undef main
@@ -37,3 +39,7 @@ void RegisterTests()
 #undef main
 #define main DEMToImageGeneratorTest
 #include "DEMToImageGenerator.cxx"
+
+#undef main
+#define main ImageToKmzChain
+#include "ImageToKmzChain.cxx"
diff --git a/Testing/Code/IO/CMakeLists.txt b/Testing/Code/IO/CMakeLists.txt
index e21735c17e525fb6713c6ea4f7034faef9ec221a..50874e532dc6121fae4bf0038e7e1ab30c6fb66f 100644
--- a/Testing/Code/IO/CMakeLists.txt
+++ b/Testing/Code/IO/CMakeLists.txt
@@ -2696,6 +2696,41 @@ ADD_TEST(ioTvMapFileProductWriter ${IO_TESTS21}
   256
 )
 
+ADD_TEST(ioTuKmzProductWriterNew ${IO_TESTS21}
+  otbKmzProductWriterNew
+)
+
+ADD_TEST(ioTvKmzProductWriterWithGCP ${IO_TESTS21}
+  otbKmzProductWriter
+  ${INPUTDATA}/Haiti1.jpeg
+  ${TEMP}/ioTuHaitiKmzProduct.kmz
+  1980.000000 1986.000000 -72.351257 18.555075 0.000000 
+  1963.000000 1944.000000 -72.352051 18.556946 0.000000
+  2078.000000 1566.000000 -72.346130 18.574358 0.000000
+  2154.000000 1430.000000 -72.342377 18.580441 0.000000
+  2432.000000 1408.000000 -72.328964 18.581335 0.000000
+  2558.000000 934.000000 -72.322571 18.602974 0.000000
+  3492.000000 1397.000000 -72.278343 18.580887 0.000000
+  2890.000000 1439.000000 -72.306908 18.579464 0.000000
+  2098.000000 2469.000000 -72.345741 18.532839 0.000000
+  1941.000000 2473.000000 -72.353317 18.532595 0.00000 
+  1644.000000 2409.000000 -72.367691 18.535810 0.000000
+  1440.000000 2448.000000 -72.377457 18.534243 0.000000
+  687.000000 2005.000000 -72.413315 18.554974 0.000000
+  741.000000 2366.000000 -72.410934 18.538496 0.000000
+  855.000000 2802.000000 -72.405739 18.518456 0.000000
+  1936.000000 2855.000000 -72.353920 18.515240 0.000000
+  3338.000000 2824.000000 -72.286240 18.515160 0.000000
+  3715.000000 1772.000000 -72.267570 18.563681 0.000000
+  3676.000000 1580.000000 -72.269203 18.572529 0.000000
+  3395.000000 931.000000 -72.282402 18.602425 0.000000
+  3426.000000 856.000000 -72.280792 18.605862 0.000000
+  2822.000000 707.000000 -72.309692 18.613203 0.000000
+  1891.000000 360.000000 -72.354301 18.629776 0.000000
+  3989.000000 2639.000000 -72.255020 18.523664 0.000000
+  417.000000 2317.000000 -72.426552 18.540876 0.000000
+  )
+
 ADD_TEST(ioTuTileMapImageIOHelperNew ${IO_TESTS21}
   otbTileMapImageIOHelperNew
 )
@@ -2982,6 +3017,7 @@ SET(BasicIO_SRCS21
 otbIOTests21.cxx
 otbMapFileProductWriterNew.cxx
 otbMapFileProductWriter.cxx
+otbKmzProductWriter.cxx
 otbTileMapImageIOHelperTest.cxx
 otbComplexImageManipulationTest.cxx
 )
diff --git a/Testing/Code/IO/otbIOTests21.cxx b/Testing/Code/IO/otbIOTests21.cxx
index 964dd2df95be43dfd70482739ba55a295708b91d..84ce0b3b3692f403dbb29cc505721125ce56ec4a 100644
--- a/Testing/Code/IO/otbIOTests21.cxx
+++ b/Testing/Code/IO/otbIOTests21.cxx
@@ -28,6 +28,8 @@ void RegisterTests()
 {
   REGISTER_TEST(otbMapFileProductWriterNew);
   REGISTER_TEST(otbMapFileProductWriter);
+  REGISTER_TEST(otbKmzProductWriterNew);
+  REGISTER_TEST(otbKmzProductWriter);
   REGISTER_TEST(otbTileMapImageIOHelperNew);
   REGISTER_TEST(otbTileMapImageIOHelperTest);
   // Complex tests
diff --git a/Testing/Code/IO/otbKmzProductWriter.cxx b/Testing/Code/IO/otbKmzProductWriter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..22a70c4419553839095b470800011983d74e526a
--- /dev/null
+++ b/Testing/Code/IO/otbKmzProductWriter.cxx
@@ -0,0 +1,95 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+#include "otbMacro.h"
+#include "otbVectorImage.h"
+#include "otbImageFileReader.h"
+#include "otbKmzProductWriter.h"
+#include "otbGCPsToRPCSensorModelImageFilter.h"
+
+typedef otb::VectorImage<float, 2>           ImageType;
+typedef otb::KmzProductWriter<ImageType>     KmzProductWriterType;
+
+int otbKmzProductWriterNew(int argc, char* argv[])
+{
+  KmzProductWriterType::Pointer  kmzWriter  = KmzProductWriterType::New();
+  return EXIT_SUCCESS;
+}
+
+int otbKmzProductWriter(int argc, char* argv[])
+{
+
+  if (argc < 3)
+    {
+    std::cerr << "Usage: " << argv[0] << " infname kmzFileName a1x a1y b1x b1y b1z ... aNx aNy aNz bNx bNy bNz" << std::endl;
+    return EXIT_FAILURE;
+    }
+  else if ((argc - 3) % 5 != 0)
+    {
+    std::cout <<"argc " << argc << std::endl;
+    std::cerr << "Inconsistent GCPs description!" << std::endl;
+    return EXIT_FAILURE;
+    }
+
+  const char * infname       = argv[1];
+  const char * kmzFileName   = argv[2];
+  
+  typedef otb::ImageFileReader<ImageType>                 ReaderType;
+  typedef otb::GCPsToRPCSensorModelImageFilter<ImageType> GCPsToSensorModelFilterType;
+  typedef GCPsToSensorModelFilterType::Point2DType        Point2DType;
+  typedef GCPsToSensorModelFilterType::Point3DType        Point3DType;
+
+  ReaderType::Pointer reader = ReaderType::New();
+  reader->SetFileName(infname);
+
+  GCPsToSensorModelFilterType::Pointer rpcEstimator = GCPsToSensorModelFilterType::New();
+  rpcEstimator->SetInput(reader->GetOutput());
+
+  unsigned int nbGCPs = (argc - 3) / 5;
+
+  std::cout << "Receiving " << nbGCPs << " from command line." << std::endl;
+
+  for (unsigned int gcpId = 0; gcpId < nbGCPs; ++gcpId)
+    {
+    Point2DType sensorPoint;
+    sensorPoint[0] = atof(argv[3 + gcpId * 5]);
+    sensorPoint[1] = atof(argv[4 + gcpId * 5]);
+
+    Point3DType geoPoint;
+    geoPoint[0] = atof(argv[5 + 5 * gcpId]);
+    geoPoint[1] = atof(argv[6 + 5 * gcpId]);
+    geoPoint[2] = atof(argv[7 + 5 * gcpId]);
+
+    std::cout << "Adding GCP sensor: " << sensorPoint << " <-> geo: " << geoPoint << std::endl;
+
+    rpcEstimator->AddGCP(sensorPoint, geoPoint);
+    }
+
+  rpcEstimator->GetOutput()->UpdateOutputInformation();
+  
+  std::cout << "Residual ground error: " << rpcEstimator->GetRMSGroundError() << std::endl;
+  
+  // Second part : Image To Kmz
+  KmzProductWriterType::Pointer    kmzWriter  = KmzProductWriterType::New();
+
+  kmzWriter->SetInput(rpcEstimator->GetOutput());
+  kmzWriter->SetPath(kmzFileName);
+  
+  kmzWriter->Update();
+
+  return EXIT_SUCCESS;
+}