diff --git a/Modules/Core/ImageBase/include/otbImage.h b/Modules/Core/ImageBase/include/otbImage.h
index c13d9b9c72021ba2dbcab2ea2300db2d2d983952..0921e060be689ed2bae119a02f51f8c878cf8aa0 100644
--- a/Modules/Core/ImageBase/include/otbImage.h
+++ b/Modules/Core/ImageBase/include/otbImage.h
@@ -174,6 +174,15 @@ public:
   /** Get the six coefficients of affine geoTtransform. */
   virtual VectorType GetGeoTransform(void) const;
 
+  /** Get signed spacing */
+  SpacingType GetSignedSpacing() const;
+
+  /** Set signed spacing */
+  virtual void SetSignedSpacing( SpacingType spacing );
+  virtual void SetSignedSpacing( double spacing[ VImageDimension ] );
+  virtual void SetSignedSpacing( float spacing[ VImageDimension ] );
+
+
   /** Get image corners. */
   virtual VectorType GetUpperLeftCorner(void) const;
   virtual VectorType GetUpperRightCorner(void) const;
diff --git a/Modules/Core/ImageBase/include/otbImage.txx b/Modules/Core/ImageBase/include/otbImage.txx
index 09e3e054e6009853ae71a38584ed2ff16298ddb3..9173f8384ffc24255376b72b41fced95ed4f5c4f 100644
--- a/Modules/Core/ImageBase/include/otbImage.txx
+++ b/Modules/Core/ImageBase/include/otbImage.txx
@@ -148,6 +148,74 @@ Image<TPixel, VImageDimension>::GetLowerRightCorner(void) const
   return (this->GetMetaDataInterface()->GetLowerRightCorner());
 }
 
+template <class TPixel, unsigned int VImageDimension>
+typename Image<TPixel, VImageDimension>::SpacingType
+Image<TPixel, VImageDimension>::GetSignedSpacing() const
+{
+  auto spacing = this->GetSpacing();
+  for ( unsigned int i = 0; i < Image::ImageDimension; ++i )
+    {
+    if (this->m_Direction[i][i] < 0 )
+      spacing[i] = - spacing[i];
+    }
+  return spacing;
+}
+
+template <class TPixel, unsigned int VImageDimension>
+void Image<TPixel, VImageDimension>
+::SetSignedSpacing( SpacingType spacing)
+{
+
+  for ( unsigned int i = 0; i < VImageDimension; i++ )
+    {
+    if ( spacing[i] < 0.0 )
+      {
+        for ( unsigned j = 0; j < VImageDimension; ++j )
+          {
+          this->m_Direction[j][i] = - this->m_Direction[j][i];
+          }
+        spacing[i] = - spacing[i];
+      }
+    }
+  this->SetSpacing(spacing);
+}
+
+template <class TPixel, unsigned int VImageDimension>
+void Image<TPixel, VImageDimension>
+::SetSignedSpacing( double spacing[ VImageDimension ])
+{
+  for ( unsigned int i = 0; i < VImageDimension; i++ )
+    {
+    if ( spacing[i] < 0.0 )
+      {
+      for ( unsigned j = 0; j < VImageDimension; ++j )
+        {
+        this->m_Direction[j][i] = - this->m_Direction[j][i];
+        }
+      spacing[i] = - spacing[i];
+      }
+    }
+  this->SetSpacing(spacing);
+}
+
+template <class TPixel, unsigned int VImageDimension>
+void Image<TPixel, VImageDimension>
+::SetSignedSpacing( float spacing[ VImageDimension ])
+{
+  for ( unsigned int i = 0; i < VImageDimension; i++ )
+    {
+    if ( spacing[i] < 0.0 )
+      {
+      for ( unsigned j = 0; j < ImageDimension; ++j )
+        {
+        this->m_Direction[j][i] = - this->m_Direction[j][i];
+        }
+      spacing[i] = - spacing[i];
+      }
+    }
+  this->SetSpacing(spacing);
+}
+
 template <class TPixel, unsigned int VImageDimension>
 typename Image<TPixel, VImageDimension>::ImageKeywordlistType
 Image<TPixel, VImageDimension>::GetImageKeywordlist(void)
diff --git a/Modules/Core/ImageBase/include/otbVectorImage.h b/Modules/Core/ImageBase/include/otbVectorImage.h
index d867f4875750c1138c882602145dffc6a4261326..dd4e7760c6747422220f524f92f2df907461e2ad 100644
--- a/Modules/Core/ImageBase/include/otbVectorImage.h
+++ b/Modules/Core/ImageBase/include/otbVectorImage.h
@@ -144,6 +144,14 @@ public:
   /** Get the six coefficients of affine geoTtransform. */
   virtual VectorType GetGeoTransform(void) const;
 
+    /** Get signed spacing */
+  SpacingType GetSignedSpacing() const;
+
+  /** Set signed spacing */
+  virtual void SetSignedSpacing( SpacingType spacing );
+  virtual void SetSignedSpacing( double spacing[ VImageDimension ] );
+  virtual void SetSignedSpacing( float spacing[ VImageDimension ] );
+
   /** Get image corners. */
   virtual VectorType GetUpperLeftCorner(void) const;
   virtual VectorType GetUpperRightCorner(void) const;
diff --git a/Modules/Core/ImageBase/include/otbVectorImage.txx b/Modules/Core/ImageBase/include/otbVectorImage.txx
index ef89e660d6b0ff3f079c4d08d2d1de6c03e2bcf0..adb6bf42cc0332d4d8f5e6f0666109ad5003a344 100644
--- a/Modules/Core/ImageBase/include/otbVectorImage.txx
+++ b/Modules/Core/ImageBase/include/otbVectorImage.txx
@@ -150,6 +150,74 @@ VectorImage<TPixel, VImageDimension>::GetLowerRightCorner(void) const
   return (this->GetMetaDataInterface()->GetLowerRightCorner());
 }
 
+template <class TPixel, unsigned int VImageDimension>
+typename VectorImage<TPixel, VImageDimension>::SpacingType
+VectorImage<TPixel, VImageDimension>::GetSignedSpacing() const
+{
+  auto spacing = this->GetSpacing();
+  for ( unsigned int i = 0; i < VImageDimension; ++i )
+    {
+    if (this->m_Direction[i][i] < 0 )
+      spacing[i] = - spacing[i];
+    }
+  return spacing;
+}
+
+template <class TPixel, unsigned int VImageDimension>
+void VectorImage<TPixel, VImageDimension>
+::SetSignedSpacing( SpacingType spacing)
+{
+
+  for ( unsigned int i = 0; i < VImageDimension; i++ )
+    {
+    if ( spacing[i] < 0.0 )
+      {
+        for ( unsigned j = 0; j < VImageDimension; ++j )
+          {
+          this->m_Direction[j][i] = - this->m_Direction[j][i];
+          }
+        spacing[i] = - spacing[i];
+      }
+    }
+  this->SetSpacing(spacing);
+}
+
+template <class TPixel, unsigned int VImageDimension>
+void VectorImage<TPixel, VImageDimension>
+::SetSignedSpacing( double spacing[ VImageDimension ])
+{
+  for ( unsigned int i = 0; i < VImageDimension; i++ )
+    {
+    if ( spacing[i] < 0.0 )
+      {
+      for ( unsigned j = 0; j < VImageDimension; ++j )
+        {
+        this->m_Direction[j][i] = - this->m_Direction[j][i];
+        }
+      spacing[i] = - spacing[i];
+      }
+    }
+  this->SetSpacing(spacing);
+}
+
+template <class TPixel, unsigned int VImageDimension>
+void VectorImage<TPixel, VImageDimension>
+::SetSignedSpacing( float spacing[ VImageDimension ])
+{
+  for ( unsigned int i = 0; i < VImageDimension; i++ )
+    {
+    if ( spacing[i] < 0.0 )
+      {
+      for ( unsigned j = 0; j < VImageDimension; ++j )
+        {
+        this->m_Direction[j][i] = - this->m_Direction[j][i];
+        }
+      spacing[i] = - spacing[i];
+      }
+    }
+  this->SetSpacing(spacing);
+}
+
 template <class TPixel, unsigned int VImageDimension>
 typename VectorImage<TPixel, VImageDimension>::ImageKeywordlistType
 VectorImage<TPixel, VImageDimension>::GetImageKeywordlist(void)
diff --git a/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx b/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx
index 812c938e6b86b6dd5005abc9939e5275b639f8e5..28d6700f5221625e7e31a09540404f444941802c 100644
--- a/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx
+++ b/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx
@@ -1686,8 +1686,8 @@ void GDALImageIO::InternalWriteImageInformation(const void* buffer)
   if (projectionRef.empty()
       &&  (vcl_abs(m_Origin[0] - 0.5) > Epsilon
            || vcl_abs(m_Origin[1] - 0.5) > Epsilon
-           || vcl_abs(m_Spacing[0] - 1.0) > Epsilon
-           || vcl_abs(m_Spacing[1] - 1.0) > Epsilon) )
+           || vcl_abs(m_Spacing[0] * m_Direction[0][0] - 1.0) > Epsilon
+           || vcl_abs(m_Spacing[1] * m_Direction[1][1] - 1.0) > Epsilon) )
     {
     // See issue #303 :
     // If there is no ProjectionRef, and the GeoTransform is not the identity,
@@ -1768,18 +1768,18 @@ void GDALImageIO::InternalWriteImageInformation(const void* buffer)
   /* -------------------------------------------------------------------- */
   if ( vcl_abs(m_Origin[0] - 0.5) > Epsilon
     || vcl_abs(m_Origin[1] - 0.5) > Epsilon
-    || vcl_abs(m_Spacing[0] - 1.0) > Epsilon
-    || vcl_abs(m_Spacing[1] - 1.0) > Epsilon )
+    || vcl_abs(m_Spacing[0] * m_Direction[0][0] - 1.0) > Epsilon
+    || vcl_abs(m_Spacing[1] * m_Direction[1][1] - 1.0) > Epsilon )
     {
     // Only set the geotransform if it is not identity (it may erase GCP)
     itk::VariableLengthVector<double> geoTransform(6);
     /// Reporting origin and spacing
     // Beware : GDAL origin is at the corner of the top-left pixel
     // whereas OTB/ITK origin is at the centre of the top-left pixel
-    geoTransform[0] = m_Origin[0] - 0.5*m_Spacing[0];
-    geoTransform[3] = m_Origin[1] - 0.5*m_Spacing[1];
-    geoTransform[1] = m_Spacing[0];
-    geoTransform[5] = m_Spacing[1];
+    geoTransform[0] = m_Origin[0] - 0.5 * m_Spacing[0] * m_Direction[0][0];
+    geoTransform[3] = m_Origin[1] - 0.5 * m_Spacing[1] * m_Direction[1][1];
+    geoTransform[1] = m_Spacing[0] * m_Direction[0][0];
+    geoTransform[5] = m_Spacing[1] * m_Direction[1][1];
 
     // FIXME: Here component 1 and 4 should be replaced by the orientation parameters
     geoTransform[2] = 0.;