Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL
4 : * Purpose: Implements Geolocation array based transformer.
5 : * Author: Even Rouault, <even.rouault at spatialys.com>
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2022, Planet Labs
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #ifndef GDALGEOLOC_H
14 : #define GDALGEOLOC_H
15 :
16 : #include "gdal_alg_priv.h"
17 :
18 : /************************************************************************/
19 : /* GDALGeoLoc */
20 : /************************************************************************/
21 :
22 : /*! @cond Doxygen_Suppress */
23 :
24 : template <class Accessors> struct GDALGeoLoc
25 : {
26 : static void LoadGeolocFinish(GDALGeoLocTransformInfo *psTransform);
27 :
28 : static bool GenerateBackMap(GDALGeoLocTransformInfo *psTransform);
29 :
30 : static bool PixelLineToXY(const GDALGeoLocTransformInfo *psTransform,
31 : const int nGeoLocPixel, const int nGeoLocLine,
32 : double &dfX, double &dfY);
33 :
34 : static bool PixelLineToXY(const GDALGeoLocTransformInfo *psTransform,
35 : const double dfGeoLocPixel,
36 : const double dfGeoLocLine, double &dfX,
37 : double &dfY);
38 :
39 : static bool ExtractSquare(const GDALGeoLocTransformInfo *psTransform,
40 : int nX, int nY, double &dfX_0_0, double &dfY_0_0,
41 : double &dfX_1_0, double &dfY_1_0, double &dfX_0_1,
42 : double &dfY_0_1, double &dfX_1_1,
43 : double &dfY_1_1);
44 :
45 : static int Transform(void *pTransformArg, int bDstToSrc, int nPointCount,
46 : double *padfX, double *padfY, double * /* padfZ */,
47 : int *panSuccess);
48 : };
49 :
50 : /*! @endcond */
51 :
52 : bool GDALGeoLocExtractSquare(const GDALGeoLocTransformInfo *psTransform, int nX,
53 : int nY, double &dfX_0_0, double &dfY_0_0,
54 : double &dfX_1_0, double &dfY_1_0, double &dfX_0_1,
55 : double &dfY_0_1, double &dfX_1_1, double &dfY_1_1);
56 :
57 : void GDALInverseBilinearInterpolation(const double x, const double y,
58 : const double x0, const double y0,
59 : const double x1, const double y1,
60 : const double x2, const double y2,
61 : const double x3, const double y3,
62 : double &i, double &j);
63 :
64 : /************************************************************************/
65 : /* ShiftGeoX() */
66 : /************************************************************************/
67 :
68 : // Avoid discontinuity at anti-meridian when interpolating longitude
69 : // dfXRef is a "reference" longitude, typically the one of 4 points to
70 : // interpolate), towards which we apply a potential +/- 360 deg shift.
71 : // This may result in a value slightly outside [-180,180]
72 3740090 : static double ShiftGeoX(const GDALGeoLocTransformInfo *psTransform,
73 : double dfXRef, double dfX)
74 : {
75 3740090 : if (!psTransform->bGeographicSRSWithMinus180Plus180LongRange)
76 628467 : return dfX;
77 : // The threshold at 170 deg is a bit arbitrary. A smarter approach
78 : // would try to guess the "average" longitude step between 2 grid values
79 : // and use 180 - average_step * some_factor as the threshold.
80 3111620 : if (dfXRef < -170 && dfX > 170)
81 9982 : return dfX - 360;
82 3101640 : if (dfXRef > 170 && dfX < -170)
83 0 : return dfX + 360;
84 3101640 : return dfX;
85 : }
86 :
87 : #endif
|