Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Name: gdal_geotransform.h 4 : * Project: GDAL Core 5 : * Purpose: Declaration of GDALGeoTransform class 6 : * Author: Even Rouault, <even.rouault@spatialys.com> 7 : * 8 : ****************************************************************************** 9 : * Copyright (c) 2025, Even Rouault, <even.rouault@spatialys.com> 10 : * 11 : * SPDX-License-Identifier: MIT 12 : ****************************************************************************/ 13 : 14 : #ifndef GDALGEOTRANSFORM_H_INCLUDED 15 : #define GDALGEOTRANSFORM_H_INCLUDED 16 : 17 : #include "gdal.h" 18 : 19 : /* ******************************************************************** */ 20 : /* GDALGeoTransform */ 21 : /* ******************************************************************** */ 22 : 23 : /** Class that encapsulates a geotransform matrix. 24 : * 25 : * It contains 6 coefficients expressing an affine transformation from 26 : * (column, line) raster space to (X, Y) georeferenced space, such that 27 : * 28 : * \code{.c} 29 : * X = xorig + column * xscale + line * xrot; 30 : * Y = yorig + column * yrot + line * yscale; 31 : * \endcode 32 : * 33 : * The default value is the identity transformation. 34 : * 35 : * @since 3.12 36 : */ 37 : class GDALGeoTransform 38 : { 39 : public: 40 : // NOTE to GDAL developers: do not reorder those coefficients! 41 : 42 : /** X value of the origin of the raster */ 43 : double xorig = 0; 44 : 45 : /** X scale factor */ 46 : double xscale = 1; 47 : 48 : /** X rotation factor */ 49 : double xrot = 0; 50 : 51 : /** Y value of the origin of the raster */ 52 : double yorig = 0; 53 : 54 : /** Y rotation factor */ 55 : double yrot = 0; 56 : 57 : /** Y scale factor */ 58 : double yscale = 1; 59 : 60 : /** Default constructor for an identity geotransformation matrix. */ 61 189270 : inline GDALGeoTransform() = default; 62 : 63 : /** Constructor from a array of 6 double */ 64 93 : inline explicit GDALGeoTransform(const double coeffs[6]) 65 93 : { 66 : static_assert(sizeof(GDALGeoTransform) == 6 * sizeof(double), 67 : "Wrong size for GDALGeoTransform"); 68 93 : xorig = coeffs[0]; 69 93 : xscale = coeffs[1]; 70 93 : xrot = coeffs[2]; 71 93 : yorig = coeffs[3]; 72 93 : yrot = coeffs[4]; 73 93 : yscale = coeffs[5]; 74 93 : } 75 : 76 : /** Constructor from 6 double values */ 77 6314 : inline GDALGeoTransform(double xorigIn, double xscaleIn, double xrotIn, 78 : double yorigIn, double yrotIn, double yscaleIn) 79 6314 : { 80 6314 : xorig = xorigIn; 81 6314 : xscale = xscaleIn; 82 6314 : xrot = xrotIn; 83 6314 : yorig = yorigIn; 84 6314 : yrot = yrotIn; 85 6314 : yscale = yscaleIn; 86 6314 : } 87 : 88 : /** Element accessor. idx must be in [0,5] range */ 89 13734 : template <typename T> inline double operator[](T idx) const 90 : { 91 13734 : return *(&xorig + idx); 92 : } 93 : 94 : /** Element accessor. idx must be in [0,5] range */ 95 81553747 : template <typename T> inline double &operator[](T idx) 96 : { 97 81553747 : return *(&xorig + idx); 98 : } 99 : 100 : /** Equality test operator */ 101 4139 : inline bool operator==(const GDALGeoTransform &other) const 102 : { 103 3044 : return xorig == other.xorig && xscale == other.xscale && 104 3020 : xrot == other.xrot && yorig == other.yorig && 105 7183 : yrot == other.yrot && yscale == other.yscale; 106 : } 107 : 108 : /** Inequality test operator */ 109 4076 : inline bool operator!=(const GDALGeoTransform &other) const 110 : { 111 4076 : return !(operator==(other)); 112 : } 113 : 114 : /** Cast to const double* */ 115 5973 : inline const double *data() const 116 : { 117 5973 : return &xorig; 118 : } 119 : 120 : /** Cast to double* */ 121 24773 : inline double *data() 122 : { 123 24773 : return &xorig; 124 : } 125 : 126 : /** 127 : * Apply GeoTransform to x/y coordinate. 128 : * 129 : * Applies the following computation, converting a (pixel, line) coordinate 130 : * into a georeferenced (geo_x, geo_y) location. 131 : * \code{.c} 132 : * *pdfGeoX = padfGeoTransform[0] + dfPixel * padfGeoTransform[1] 133 : * + dfLine * padfGeoTransform[2]; 134 : * *pdfGeoY = padfGeoTransform[3] + dfPixel * padfGeoTransform[4] 135 : * + dfLine * padfGeoTransform[5]; 136 : * \endcode 137 : * 138 : * @param dfPixel Input pixel position. 139 : * @param dfLine Input line position. 140 : * @param pdfGeoX output location where geo_x (easting/longitude) 141 : * location is placed. 142 : * @param pdfGeoY output location where geo_y (northing/latitude) 143 : * location is placed. 144 : */ 145 : 146 5816 : inline void Apply(double dfPixel, double dfLine, double *pdfGeoX, 147 : double *pdfGeoY) const 148 : { 149 5816 : GDALApplyGeoTransform(data(), dfPixel, dfLine, pdfGeoX, pdfGeoY); 150 5816 : } 151 : 152 : /** 153 : * Invert Geotransform. 154 : * 155 : * This function will invert a standard 3x2 set of GeoTransform coefficients. 156 : * This converts the equation from being pixel to geo to being geo to pixel. 157 : * 158 : * @param[out] inverse Output geotransform 159 : * 160 : * @return true on success or false if the equation is uninvertable. 161 : */ 162 157 : inline bool GetInverse(GDALGeoTransform &inverse) const 163 : { 164 157 : return GDALInvGeoTransform(data(), inverse.data()) == TRUE; 165 : } 166 : 167 : /** Rescale a geotransform by multiplying its scale and rotation terms by 168 : * the provided ratios. 169 : * 170 : * This is typically used to compute the geotransform matrix of an overview 171 : * dataset from the full resolution dataset, where the ratios are the size 172 : * of the full resolution dataset divided by the size of the overview. 173 : */ 174 1855 : inline void Rescale(double dfXRatio, double dfYRatio) 175 : { 176 1855 : xscale *= dfXRatio; 177 1855 : xrot *= dfYRatio; 178 1855 : yrot *= dfXRatio; 179 1855 : yscale *= dfYRatio; 180 1855 : } 181 : }; 182 : 183 : #endif