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.;