Coverage Report

Created: 2025-08-29 07:11

/src/PROJ/src/grids.hpp
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 * Project:  PROJ
3
 * Purpose:  Grid management
4
 * Author:   Even Rouault, <even.rouault at spatialys.com>
5
 *
6
 ******************************************************************************
7
 * Copyright (c) 2019, Even Rouault, <even.rouault at spatialys.com>
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a
10
 * copy of this software and associated documentation files (the "Software"),
11
 * to deal in the Software without restriction, including without limitation
12
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13
 * and/or sell copies of the Software, and to permit persons to whom the
14
 * Software is furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included
17
 * in all copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
 * DEALINGS IN THE SOFTWARE.
26
 *****************************************************************************/
27
28
#ifndef GRIDS_HPP_INCLUDED
29
#define GRIDS_HPP_INCLUDED
30
31
#include <memory>
32
#include <vector>
33
34
#include "proj.h"
35
#include "proj/util.hpp"
36
37
NS_PROJ_START
38
39
struct ExtentAndRes {
40
    bool isGeographic; // whether extent and resolutions are in a geographic or
41
                       // projected CRS
42
    double west;       // in radian for geographic, in CRS units otherwise
43
    double south;      // in radian for geographic, in CRS units otherwise
44
    double east;       // in radian for geographic, in CRS units otherwise
45
    double north;      // in radian for geographic, in CRS units otherwise
46
    double resX;       // in radian for geographic, in CRS units otherwise
47
    double resY;       // in radian for geographic, in CRS units otherwise
48
    double invResX;    // = 1 / resX;
49
    double invResY;    // = 1 / resY;
50
51
    void computeInvRes();
52
53
    bool fullWorldLongitude() const;
54
    bool contains(const ExtentAndRes &other) const;
55
    bool intersects(const ExtentAndRes &other) const;
56
};
57
58
// ---------------------------------------------------------------------------
59
60
class PROJ_GCC_DLL Grid {
61
  protected:
62
    friend class GTiffDataset;
63
    std::string m_name;
64
    int m_width;
65
    int m_height;
66
    ExtentAndRes m_extent;
67
68
    Grid(const std::string &nameIn, int widthIn, int heightIn,
69
         const ExtentAndRes &extentIn);
70
71
  public:
72
    PROJ_FOR_TEST virtual ~Grid();
73
74
0
    PROJ_FOR_TEST int width() const { return m_width; }
75
0
    PROJ_FOR_TEST int height() const { return m_height; }
76
0
    PROJ_FOR_TEST const ExtentAndRes &extentAndRes() const { return m_extent; }
77
0
    PROJ_FOR_TEST const std::string &name() const { return m_name; }
78
79
    virtual const std::string &metadataItem(const std::string &key,
80
                                            int sample = -1) const = 0;
81
82
0
    PROJ_FOR_TEST virtual bool isNullGrid() const { return false; }
83
    PROJ_FOR_TEST virtual bool hasChanged() const = 0;
84
};
85
86
// ---------------------------------------------------------------------------
87
88
class PROJ_GCC_DLL VerticalShiftGrid : public Grid {
89
  protected:
90
    std::vector<std::unique_ptr<VerticalShiftGrid>> m_children{};
91
92
  public:
93
    PROJ_FOR_TEST VerticalShiftGrid(const std::string &nameIn, int widthIn,
94
                                    int heightIn, const ExtentAndRes &extentIn);
95
    PROJ_FOR_TEST ~VerticalShiftGrid() override;
96
97
    PROJ_FOR_TEST const VerticalShiftGrid *gridAt(double longitude,
98
                                                  double lat) const;
99
100
    PROJ_FOR_TEST virtual bool isNodata(float /*val*/,
101
                                        double /* multiplier */) const = 0;
102
103
    // x = 0 is western-most column, y = 0 is southern-most line
104
    PROJ_FOR_TEST virtual bool valueAt(int x, int y, float &out) const = 0;
105
106
    PROJ_FOR_TEST virtual void reassign_context(PJ_CONTEXT *ctx) = 0;
107
};
108
109
// ---------------------------------------------------------------------------
110
111
class PROJ_GCC_DLL VerticalShiftGridSet {
112
  protected:
113
    std::string m_name{};
114
    std::string m_format{};
115
    std::vector<std::unique_ptr<VerticalShiftGrid>> m_grids{};
116
117
    VerticalShiftGridSet();
118
119
  public:
120
    PROJ_FOR_TEST virtual ~VerticalShiftGridSet();
121
122
    PROJ_FOR_TEST static std::unique_ptr<VerticalShiftGridSet>
123
    open(PJ_CONTEXT *ctx, const std::string &filename);
124
125
0
    PROJ_FOR_TEST const std::string &name() const { return m_name; }
126
0
    PROJ_FOR_TEST const std::string &format() const { return m_format; }
127
    PROJ_FOR_TEST const std::vector<std::unique_ptr<VerticalShiftGrid>> &
128
0
    grids() const {
129
0
        return m_grids;
130
0
    }
131
    PROJ_FOR_TEST const VerticalShiftGrid *gridAt(double longitude,
132
                                                  double lat) const;
133
134
    PROJ_FOR_TEST virtual void reassign_context(PJ_CONTEXT *ctx);
135
    PROJ_FOR_TEST virtual bool reopen(PJ_CONTEXT *ctx);
136
};
137
138
// ---------------------------------------------------------------------------
139
140
class PROJ_GCC_DLL HorizontalShiftGrid : public Grid {
141
  protected:
142
    std::vector<std::unique_ptr<HorizontalShiftGrid>> m_children{};
143
144
  public:
145
    PROJ_FOR_TEST HorizontalShiftGrid(const std::string &nameIn, int widthIn,
146
                                      int heightIn,
147
                                      const ExtentAndRes &extentIn);
148
    PROJ_FOR_TEST ~HorizontalShiftGrid() override;
149
150
    PROJ_FOR_TEST const HorizontalShiftGrid *gridAt(double longitude,
151
                                                    double lat) const;
152
153
    // x = 0 is western-most column, y = 0 is southern-most line
154
    PROJ_FOR_TEST virtual bool valueAt(int x, int y,
155
                                       bool compensateNTConvention,
156
                                       float &longShift,
157
                                       float &latShift) const = 0;
158
159
    PROJ_FOR_TEST virtual void reassign_context(PJ_CONTEXT *ctx) = 0;
160
};
161
162
// ---------------------------------------------------------------------------
163
164
class PROJ_GCC_DLL HorizontalShiftGridSet {
165
  protected:
166
    std::string m_name{};
167
    std::string m_format{};
168
    std::vector<std::unique_ptr<HorizontalShiftGrid>> m_grids{};
169
170
    HorizontalShiftGridSet();
171
172
  public:
173
    PROJ_FOR_TEST virtual ~HorizontalShiftGridSet();
174
175
    PROJ_FOR_TEST static std::unique_ptr<HorizontalShiftGridSet>
176
    open(PJ_CONTEXT *ctx, const std::string &filename);
177
178
0
    PROJ_FOR_TEST const std::string &name() const { return m_name; }
179
0
    PROJ_FOR_TEST const std::string &format() const { return m_format; }
180
    PROJ_FOR_TEST const std::vector<std::unique_ptr<HorizontalShiftGrid>> &
181
0
    grids() const {
182
0
        return m_grids;
183
0
    }
184
    PROJ_FOR_TEST const HorizontalShiftGrid *gridAt(double longitude,
185
                                                    double lat) const;
186
187
    PROJ_FOR_TEST virtual void reassign_context(PJ_CONTEXT *ctx);
188
    PROJ_FOR_TEST virtual bool reopen(PJ_CONTEXT *ctx);
189
};
190
191
// ---------------------------------------------------------------------------
192
193
class PROJ_GCC_DLL GenericShiftGrid : public Grid {
194
  protected:
195
    std::vector<std::unique_ptr<GenericShiftGrid>> m_children{};
196
197
  public:
198
    PROJ_FOR_TEST GenericShiftGrid(const std::string &nameIn, int widthIn,
199
                                   int heightIn, const ExtentAndRes &extentIn);
200
201
    PROJ_FOR_TEST ~GenericShiftGrid() override;
202
203
    PROJ_FOR_TEST const GenericShiftGrid *gridAt(double x, double y) const;
204
205
    virtual const std::string &type() const = 0;
206
207
    PROJ_FOR_TEST virtual std::string unit(int sample) const = 0;
208
209
    PROJ_FOR_TEST virtual std::string description(int sample) const = 0;
210
211
    PROJ_FOR_TEST virtual int samplesPerPixel() const = 0;
212
213
    // x = 0 is western-most column, y = 0 is southern-most line
214
    PROJ_FOR_TEST virtual bool valueAt(int x, int y, int sample,
215
                                       float &out) const = 0;
216
217
    PROJ_FOR_TEST virtual bool valuesAt(int x_start, int y_start, int x_count,
218
                                        int y_count, int sample_count,
219
                                        const int *sample_idx, float *out,
220
                                        bool &nodataFound) const;
221
222
    PROJ_FOR_TEST virtual void reassign_context(PJ_CONTEXT *ctx) = 0;
223
};
224
225
// ---------------------------------------------------------------------------
226
227
class PROJ_GCC_DLL GenericShiftGridSet {
228
  protected:
229
    std::string m_name{};
230
    std::string m_format{};
231
    std::vector<std::unique_ptr<GenericShiftGrid>> m_grids{};
232
233
    GenericShiftGridSet();
234
235
  public:
236
    PROJ_FOR_TEST virtual ~GenericShiftGridSet();
237
238
    PROJ_FOR_TEST static std::unique_ptr<GenericShiftGridSet>
239
    open(PJ_CONTEXT *ctx, const std::string &filename);
240
241
0
    PROJ_FOR_TEST const std::string &name() const { return m_name; }
242
0
    PROJ_FOR_TEST const std::string &format() const { return m_format; }
243
    PROJ_FOR_TEST const std::vector<std::unique_ptr<GenericShiftGrid>> &
244
4
    grids() const {
245
4
        return m_grids;
246
4
    }
247
    PROJ_FOR_TEST const GenericShiftGrid *gridAt(double x, double y) const;
248
    PROJ_FOR_TEST const GenericShiftGrid *gridAt(const std::string &type,
249
                                                 double x, double y) const;
250
251
    PROJ_FOR_TEST virtual void reassign_context(PJ_CONTEXT *ctx);
252
    PROJ_FOR_TEST virtual bool reopen(PJ_CONTEXT *ctx);
253
};
254
255
// ---------------------------------------------------------------------------
256
257
typedef std::vector<std::unique_ptr<HorizontalShiftGridSet>> ListOfHGrids;
258
typedef std::vector<std::unique_ptr<VerticalShiftGridSet>> ListOfVGrids;
259
typedef std::vector<std::unique_ptr<GenericShiftGridSet>> ListOfGenericGrids;
260
261
ListOfVGrids pj_vgrid_init(PJ *P, const char *grids);
262
ListOfHGrids pj_hgrid_init(PJ *P, const char *grids);
263
ListOfGenericGrids pj_generic_grid_init(PJ *P, const char *grids);
264
265
PJ_LP pj_hgrid_value(PJ *P, const ListOfHGrids &grids, PJ_LP lp);
266
double pj_vgrid_value(PJ *P, const ListOfVGrids &, PJ_LP lp,
267
                      double vmultiplier);
268
PJ_LP pj_hgrid_apply(PJ_CONTEXT *ctx, const ListOfHGrids &grids, PJ_LP lp,
269
                     PJ_DIRECTION direction);
270
271
const GenericShiftGrid *pj_find_generic_grid(const ListOfGenericGrids &grids,
272
                                             const PJ_LP &input,
273
                                             GenericShiftGridSet *&gridSetOut);
274
bool pj_bilinear_interpolation_three_samples(
275
    PJ_CONTEXT *ctx, const GenericShiftGrid *grid, const PJ_LP &lp, int idx1,
276
    int idx2, int idx3, double &v1, double &v2, double &v3, bool &must_retry);
277
278
NS_PROJ_END
279
280
#endif // GRIDS_HPP_INCLUDED