LCOV - code coverage report
Current view: top level - gcore - gdal_geotransform.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 49 49 100.0 %
Date: 2025-10-21 22:35:35 Functions: 15 15 100.0 %

          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             : #include <utility>
      20             : 
      21             : class GDALRasterWindow;
      22             : 
      23             : /* ******************************************************************** */
      24             : /*                             GDALGeoTransform                         */
      25             : /* ******************************************************************** */
      26             : 
      27             : /** Class that encapsulates a geotransform matrix.
      28             :  *
      29             :  * It contains 6 coefficients expressing an affine transformation from
      30             :  * (column, line) raster space to (X, Y) georeferenced space, such that
      31             :  *
      32             :  * \code{.c}
      33             :  *  X = xorig + column * xscale + line * xrot;
      34             :  *  Y = yorig + column * yrot   + line * yscale;
      35             :  * \endcode
      36             :  *
      37             :  * The default value is the identity transformation.
      38             :  *
      39             :  * @since 3.12
      40             :  */
      41             : class GDALGeoTransform
      42             : {
      43             :   public:
      44             :     // NOTE to GDAL developers: do not reorder those coefficients!
      45             : 
      46             :     /** X value of the origin of the raster */
      47             :     double xorig = 0;
      48             : 
      49             :     /** X scale factor */
      50             :     double xscale = 1;
      51             : 
      52             :     /** X rotation factor */
      53             :     double xrot = 0;
      54             : 
      55             :     /** Y value of the origin of the raster */
      56             :     double yorig = 0;
      57             : 
      58             :     /** Y rotation factor */
      59             :     double yrot = 0;
      60             : 
      61             :     /** Y scale factor */
      62             :     double yscale = 1;
      63             : 
      64             :     /** Default constructor for an identity geotransformation matrix. */
      65      194785 :     inline GDALGeoTransform() = default;
      66             : 
      67             :     /** Constructor from a array of 6 double */
      68          93 :     inline explicit GDALGeoTransform(const double coeffs[6])
      69          93 :     {
      70             :         static_assert(sizeof(GDALGeoTransform) == 6 * sizeof(double),
      71             :                       "Wrong size for GDALGeoTransform");
      72          93 :         xorig = coeffs[0];
      73          93 :         xscale = coeffs[1];
      74          93 :         xrot = coeffs[2];
      75          93 :         yorig = coeffs[3];
      76          93 :         yrot = coeffs[4];
      77          93 :         yscale = coeffs[5];
      78          93 :     }
      79             : 
      80             :     /** Constructor from 6 double values */
      81        6504 :     inline GDALGeoTransform(double xorigIn, double xscaleIn, double xrotIn,
      82             :                             double yorigIn, double yrotIn, double yscaleIn)
      83        6504 :     {
      84        6504 :         xorig = xorigIn;
      85        6504 :         xscale = xscaleIn;
      86        6504 :         xrot = xrotIn;
      87        6504 :         yorig = yorigIn;
      88        6504 :         yrot = yrotIn;
      89        6504 :         yscale = yscaleIn;
      90        6504 :     }
      91             : 
      92             :     /** Element accessor. idx must be in [0,5] range */
      93       13829 :     template <typename T> inline double operator[](T idx) const
      94             :     {
      95       13829 :         return *(&xorig + idx);
      96             :     }
      97             : 
      98             :     /** Element accessor. idx must be in [0,5] range */
      99    81777497 :     template <typename T> inline double &operator[](T idx)
     100             :     {
     101    81777497 :         return *(&xorig + idx);
     102             :     }
     103             : 
     104             :     /** Equality test operator */
     105        4325 :     inline bool operator==(const GDALGeoTransform &other) const
     106             :     {
     107        3175 :         return xorig == other.xorig && xscale == other.xscale &&
     108        3149 :                xrot == other.xrot && yorig == other.yorig &&
     109        7500 :                yrot == other.yrot && yscale == other.yscale;
     110             :     }
     111             : 
     112             :     /** Inequality test operator */
     113        4262 :     inline bool operator!=(const GDALGeoTransform &other) const
     114             :     {
     115        4262 :         return !(operator==(other));
     116             :     }
     117             : 
     118             :     /** Cast to const double* */
     119      100173 :     inline const double *data() const
     120             :     {
     121      100173 :         return &xorig;
     122             :     }
     123             : 
     124             :     /** Cast to double* */
     125       24889 :     inline double *data()
     126             :     {
     127       24889 :         return &xorig;
     128             :     }
     129             : 
     130             :     /**
     131             :      * Apply GeoTransform to x/y coordinate.
     132             :      *
     133             :      * Applies the following computation, converting a (pixel, line) coordinate
     134             :      * into a georeferenced (geo_x, geo_y) location.
     135             :      * \code{.c}
     136             :      *  *pdfGeoX = padfGeoTransform[0] + dfPixel * padfGeoTransform[1]
     137             :      *                                 + dfLine  * padfGeoTransform[2];
     138             :      *  *pdfGeoY = padfGeoTransform[3] + dfPixel * padfGeoTransform[4]
     139             :      *                                 + dfLine  * padfGeoTransform[5];
     140             :      * \endcode
     141             :      *
     142             :      * @param dfPixel Input pixel position.
     143             :      * @param dfLine Input line position.
     144             :      * @param pdfGeoX output location where geo_x (easting/longitude)
     145             :      * location is placed.
     146             :      * @param pdfGeoY output location where geo_y (northing/latitude)
     147             :      * location is placed.
     148             :      */
     149             : 
     150        8971 :     inline void Apply(double dfPixel, double dfLine, double *pdfGeoX,
     151             :                       double *pdfGeoY) const
     152             :     {
     153        8971 :         GDALApplyGeoTransform(data(), dfPixel, dfLine, pdfGeoX, pdfGeoY);
     154        8971 :     }
     155             : 
     156             :     /** Apply a geotransform to an OGREnvelope in geographic coordinates.
     157             :      *
     158             :      * @param env An envelope in geographic coordinates
     159             :      * @param window A window in pixel/line coordinates
     160             :      * @return true if the geotransform was successfully applied
     161             :      */
     162             :     bool Apply(const OGREnvelope &env, GDALRasterWindow &window) const;
     163             : 
     164             :     /** Apply a geotransform to a GDALRasterWindow in pixel/line coordinates.
     165             :      *
     166             :      * @param window A window in pixel/line coordinates
     167             :      * @param env An envelope in geographic coordinates
     168             :      * @return true if the geotransform was successfully applied
     169             :      */
     170             :     bool Apply(const GDALRasterWindow &window, OGREnvelope &env) const;
     171             : 
     172             :     /**
     173             :      * Apply GeoTransform to x/y coordinate.
     174             :      *
     175             :      * Applies the following computation, converting a (pixel, line) coordinate
     176             :      * into a georeferenced (geo_x, geo_y) location.
     177             :      * \code{.c}
     178             :      *  out.first = padfGeoTransform[0] + dfPixel * padfGeoTransform[1]
     179             :      *                                   + dfLine  * padfGeoTransform[2];
     180             :      *  out.second = padfGeoTransform[3] + dfPixel * padfGeoTransform[4]
     181             :      *                                   + dfLine  * padfGeoTransform[5];
     182             :      * \endcode
     183             :      *
     184             :      * @param dfPixel Input pixel position.
     185             :      * @param dfLine Input line position.
     186             :      * @return output location as a (geo_x, geo_y) pair
     187             :      */
     188             : 
     189       90934 :     inline std::pair<double, double> Apply(double dfPixel, double dfLine) const
     190             :     {
     191             :         double dfOutX, dfOutY;
     192       90934 :         GDALApplyGeoTransform(data(), dfPixel, dfLine, &dfOutX, &dfOutY);
     193       90934 :         return {dfOutX, dfOutY};
     194             :     }
     195             : 
     196             :     /**
     197             :      * Invert Geotransform.
     198             :      *
     199             :      * This function will invert a standard 3x2 set of GeoTransform coefficients.
     200             :      * This converts the equation from being pixel to geo to being geo to pixel.
     201             :      *
     202             :      * @param[out] inverse Output geotransform
     203             :      *
     204             :      * @return true on success or false if the equation is uninvertable.
     205             :      */
     206         268 :     inline bool GetInverse(GDALGeoTransform &inverse) const
     207             :     {
     208         268 :         return GDALInvGeoTransform(data(), inverse.data()) == TRUE;
     209             :     }
     210             : 
     211             :     /** Rescale a geotransform by multiplying its scale and rotation terms by
     212             :      * the provided ratios.
     213             :      *
     214             :      * This is typically used to compute the geotransform matrix of an overview
     215             :      * dataset from the full resolution dataset, where the ratios are the size
     216             :      * of the full resolution dataset divided by the size of the overview.
     217             :      */
     218        1947 :     inline void Rescale(double dfXRatio, double dfYRatio)
     219             :     {
     220        1947 :         xscale *= dfXRatio;
     221        1947 :         xrot *= dfYRatio;
     222        1947 :         yrot *= dfXRatio;
     223        1947 :         yscale *= dfYRatio;
     224        1947 :     }
     225             : 
     226             :     /** Check whether the geotransform has a rotation component.
     227             :      */
     228         517 :     inline bool IsAxisAligned() const
     229             :     {
     230         517 :         return xrot == 0 && yrot == 0;
     231             :     }
     232             : };
     233             : 
     234             : #endif

Generated by: LCOV version 1.14