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 : * Permission is hereby granted, free of charge, to any person obtaining a
11 : * copy of this software and associated documentation files (the "Software"),
12 : * to deal in the Software without restriction, including without limitation
13 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 : * and/or sell copies of the Software, and to permit persons to whom the
15 : * Software is furnished to do so, subject to the following conditions:
16 : *
17 : * The above copyright notice and this permission notice shall be included
18 : * in all copies or substantial portions of the Software.
19 : *
20 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 : * DEALINGS IN THE SOFTWARE.
27 : ****************************************************************************/
28 :
29 : #ifndef GDALGEOLOC_H
30 : #define GDALGEOLOC_H
31 :
32 : #include "gdal_alg_priv.h"
33 :
34 : /************************************************************************/
35 : /* GDALGeoLoc */
36 : /************************************************************************/
37 :
38 : /*! @cond Doxygen_Suppress */
39 :
40 : template <class Accessors> struct GDALGeoLoc
41 : {
42 : static void LoadGeolocFinish(GDALGeoLocTransformInfo *psTransform);
43 :
44 : static bool GenerateBackMap(GDALGeoLocTransformInfo *psTransform);
45 :
46 : static bool PixelLineToXY(const GDALGeoLocTransformInfo *psTransform,
47 : const int nGeoLocPixel, const int nGeoLocLine,
48 : double &dfX, double &dfY);
49 :
50 : static bool PixelLineToXY(const GDALGeoLocTransformInfo *psTransform,
51 : const double dfGeoLocPixel,
52 : const double dfGeoLocLine, double &dfX,
53 : double &dfY);
54 :
55 : static bool ExtractSquare(const GDALGeoLocTransformInfo *psTransform,
56 : int nX, int nY, double &dfX_0_0, double &dfY_0_0,
57 : double &dfX_1_0, double &dfY_1_0, double &dfX_0_1,
58 : double &dfY_0_1, double &dfX_1_1,
59 : double &dfY_1_1);
60 :
61 : static int Transform(void *pTransformArg, int bDstToSrc, int nPointCount,
62 : double *padfX, double *padfY, double * /* padfZ */,
63 : int *panSuccess);
64 : };
65 :
66 : /*! @endcond */
67 :
68 : bool GDALGeoLocExtractSquare(const GDALGeoLocTransformInfo *psTransform, int nX,
69 : int nY, double &dfX_0_0, double &dfY_0_0,
70 : double &dfX_1_0, double &dfY_1_0, double &dfX_0_1,
71 : double &dfY_0_1, double &dfX_1_1, double &dfY_1_1);
72 :
73 : void GDALInverseBilinearInterpolation(const double x, const double y,
74 : const double x0, const double y0,
75 : const double x1, const double y1,
76 : const double x2, const double y2,
77 : const double x3, const double y3,
78 : double &i, double &j);
79 :
80 : /************************************************************************/
81 : /* ShiftGeoX() */
82 : /************************************************************************/
83 :
84 : // Avoid discontinuity at anti-meridian when interpolating longitude
85 : // dfXRef is a "reference" longitude, typically the one of 4 points to
86 : // interpolate), towards which we apply a potential +/- 360 deg shift.
87 : // This may result in a value slightly outside [-180,180]
88 3735710 : static double ShiftGeoX(const GDALGeoLocTransformInfo *psTransform,
89 : double dfXRef, double dfX)
90 : {
91 3735710 : if (!psTransform->bGeographicSRSWithMinus180Plus180LongRange)
92 627519 : return dfX;
93 : // The threshold at 170 deg is a bit arbitrary. A smarter approach
94 : // would try to guess the "average" longitude step between 2 grid values
95 : // and use 180 - average_step * some_factor as the threshold.
96 3108190 : if (dfXRef < -170 && dfX > 170)
97 9982 : return dfX - 360;
98 3098210 : if (dfXRef > 170 && dfX < -170)
99 0 : return dfX + 360;
100 3098210 : return dfX;
101 : }
102 :
103 : #endif
|