text: /*
   * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
   *
   * This file is part of Orfeo Toolbox
   *
   *     https://www.orfeo-toolbox.org/
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  #ifndef otbKmzProductWriter_h
  #define otbKmzProductWriter_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 "otbGenericRSTransform.h"
  #include "otbStreamingShrinkImageFilter.h"
  #include "itkCastImageFilter.h"
  
  // Possibility to includes vectordatas necessary includes
  #include "otbVectorData.h"
  #include "otbVectorDataFileWriter.h"
  #include <string>
  
  
  namespace otb
  {
  
  /** \class KmzProductWriter
   * \brief This class generate a Kmz from one or several input
   * images. The inputs must have a non empty metadata information.
   *
   * This class writes kmz files, supported by Google Earth. The input
   * must have metadata (a non empty keywordlist)
   *
   * The size of the tiles can be set via the method
   * SetTileSize(unsigned int), the user can also specify the name of
   * the output Kmz filename via SetPath().
   *
   *
   *
   * \ingroup IO
   *
   *
   * \ingroup OTBKMZWriter
   */
  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 typename InputImageType::RegionType          RegionType;
    typedef unsigned char                                OutputPixelType;
    typedef typename InputImageType::Pointer             InputImagePointer;
    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;
  
    // std::pair description <-> legend (image)
    typedef std::pair<std::string, InputImagePointer>                   LegendPairType;
    typedef std::vector<LegendPairType>                                 LegendVectorType;
  
    /** Dimension of input image. */
    itkStaticConstMacro(InputImageDimension, unsigned int,
                        InputImageType::ImageDimension);
  
    using Superclass::SetInput;
    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 */
    void Update() override
    {
      this->Write();
    }
  
    /* Method to Add Logo */
    itkSetMacro(Logo, InputImagePointer);
  
    /** Method to store the legend and their description in the
      * legendVector
      */
    void AddLegend(const std::string& description, const InputImagePointer legend)
    {
      LegendPairType   legendPair;
      legendPair.first  = description;
      legendPair.second = legend;
      m_LegendVector.push_back(legendPair);
    }
  
    /** Method to add legend with empty description */
    void AddLegend(const InputImagePointer legend)
    {
      std::string emptyString ="";
      this->AddLegend(emptyString, legend);
    }
  
    /** Set the size of the tiles to produce */
    void SetTileSize(unsigned int tileSize);
  
  protected:
    KmzProductWriter();
    ~KmzProductWriter() override;
    void PrintSelf(std::ostream& os, itk::Indent indent) const override;
  
    /**Method for Tiling the input image*/
    virtual void Tiling();
  
    /** Method for writing */
    virtual void Write();
  
  private:
    KmzProductWriter(const Self &) = delete;
    void operator =(const Self&) = delete;
  
     /** 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  generate 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();
  
    // Add Legends to the root kml
    void AddLegendToRootKml(double north, double south, double east, double west);
  
    /** KML root generate */
    void GenerateKMLRoot(const 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(const std::string& pathname, int depth, int x, int y, double north, double south, double east, double west);
  
    void GenerateKMLExtended(const std::string& pathname,
                             int depth,
                             int x,
                             int y,
                             OutputPointType lowerLeft,
                             OutputPointType lowerRight,
                             OutputPointType upperRight,
                             OutputPointType upperLeft);
  
    /** KML with link generate */
    void GenerateKMLWithLink(const 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(const 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,
                                 const 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(const std::ostringstream&  absolutePath, const std::ostringstream&   kmz_in_path);
  
    /**Cut the image file name to built the directory name*/
    std::string GetCuttenFileName(const std::string& description, unsigned int idx);
  
    /** Method to add logo if any */
    void AddLogo();
  
    /** Method to add Legend if any */
    void ProcessLegends();
  
    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
    unsigned 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;
  
    // Logo
    InputImagePointer      m_Logo;
  
    // Vector used to store legend and description
    LegendVectorType       m_LegendVector;
  };
  
  } // end namespace otb
  
  #ifndef OTB_MANUAL_INSTANTIATION
  #include "otbKmzProductWriter.hxx"
  #endif
  
  #endif
  