Coverage Report

Created: 2024-02-25 06:14

/src/PROJ/src/iso19111/operation/coordinateoperation_internal.hpp
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Project:  PROJ
4
 * Purpose:  ISO19111:2019 implementation
5
 * Author:   Even Rouault <even dot rouault at spatialys dot com>
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
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 FROM_PROJ_CPP
30
#error This file should only be included from a PROJ cpp file
31
#endif
32
33
#ifndef COORDINATEOPERATION_INTERNAL_HH_INCLUDED
34
#define COORDINATEOPERATION_INTERNAL_HH_INCLUDED
35
36
#include "proj/coordinateoperation.hpp"
37
38
#include <vector>
39
40
//! @cond Doxygen_Suppress
41
42
NS_PROJ_START
43
44
namespace operation {
45
46
// ---------------------------------------------------------------------------
47
48
bool isAxisOrderReversal(int methodEPSGCode);
49
50
// ---------------------------------------------------------------------------
51
52
class InverseCoordinateOperation;
53
/** Shared pointer of InverseCoordinateOperation */
54
using InverseCoordinateOperationPtr =
55
    std::shared_ptr<InverseCoordinateOperation>;
56
/** Non-null shared pointer of InverseCoordinateOperation */
57
using InverseCoordinateOperationNNPtr = util::nn<InverseCoordinateOperationPtr>;
58
59
/** \brief Inverse operation of a CoordinateOperation.
60
 *
61
 * This is used when there is no straightforward way of building another
62
 * subclass of CoordinateOperation that models the inverse operation.
63
 */
64
class InverseCoordinateOperation : virtual public CoordinateOperation {
65
  public:
66
    InverseCoordinateOperation(
67
        const CoordinateOperationNNPtr &forwardOperationIn,
68
        bool wktSupportsInversion);
69
70
    ~InverseCoordinateOperation() override;
71
72
    void _exportToPROJString(io::PROJStringFormatter *formatter)
73
        const override; // throw(FormattingException)
74
75
    bool _isEquivalentTo(
76
        const util::IComparable *other,
77
        util::IComparable::Criterion criterion =
78
            util::IComparable::Criterion::STRICT,
79
        const io::DatabaseContextPtr &dbContext = nullptr) const override;
80
81
    CoordinateOperationNNPtr inverse() const override;
82
83
1.45k
    const CoordinateOperationNNPtr &forwardOperation() const {
84
1.45k
        return forwardOperation_;
85
1.45k
    }
86
87
  protected:
88
    CoordinateOperationNNPtr forwardOperation_;
89
    bool wktSupportsInversion_;
90
91
    void setPropertiesFromForward();
92
};
93
94
// ---------------------------------------------------------------------------
95
96
/** \brief Inverse of a conversion. */
97
class InverseConversion : public Conversion, public InverseCoordinateOperation {
98
  public:
99
    explicit InverseConversion(const ConversionNNPtr &forward);
100
101
    ~InverseConversion() override;
102
103
0
    void _exportToWKT(io::WKTFormatter *formatter) const override {
104
0
        Conversion::_exportToWKT(formatter);
105
0
    }
106
107
0
    void _exportToJSON(io::JSONFormatter *formatter) const override {
108
0
        Conversion::_exportToJSON(formatter);
109
0
    }
110
111
    void
112
6.37k
    _exportToPROJString(io::PROJStringFormatter *formatter) const override {
113
6.37k
        InverseCoordinateOperation::_exportToPROJString(formatter);
114
6.37k
    }
115
116
    bool _isEquivalentTo(
117
        const util::IComparable *other,
118
        util::IComparable::Criterion criterion =
119
            util::IComparable::Criterion::STRICT,
120
2.59k
        const io::DatabaseContextPtr &dbContext = nullptr) const override {
121
2.59k
        return InverseCoordinateOperation::_isEquivalentTo(other, criterion,
122
2.59k
                                                           dbContext);
123
2.59k
    }
124
125
3.04k
    CoordinateOperationNNPtr inverse() const override {
126
3.04k
        return InverseCoordinateOperation::inverse();
127
3.04k
    }
128
129
    ConversionNNPtr inverseAsConversion() const;
130
131
#ifdef _MSC_VER
132
    // To avoid a warning C4250: 'osgeo::proj::operation::InverseConversion':
133
    // inherits
134
    // 'osgeo::proj::operation::SingleOperation::osgeo::proj::operation::SingleOperation::gridsNeeded'
135
    // via dominance
136
    std::set<GridDescription>
137
    gridsNeeded(const io::DatabaseContextPtr &databaseContext,
138
                bool considerKnownGridsAsAvailable) const override {
139
        return SingleOperation::gridsNeeded(databaseContext,
140
                                            considerKnownGridsAsAvailable);
141
    }
142
#endif
143
144
    static CoordinateOperationNNPtr create(const ConversionNNPtr &forward);
145
146
    CoordinateOperationNNPtr _shallowClone() const override;
147
};
148
149
// ---------------------------------------------------------------------------
150
151
/** \brief Inverse of a transformation. */
152
class InverseTransformation : public Transformation,
153
                              public InverseCoordinateOperation {
154
  public:
155
    explicit InverseTransformation(const TransformationNNPtr &forward);
156
157
    ~InverseTransformation() override;
158
159
    void _exportToWKT(io::WKTFormatter *formatter) const override;
160
161
    void
162
3.42k
    _exportToPROJString(io::PROJStringFormatter *formatter) const override {
163
3.42k
        return InverseCoordinateOperation::_exportToPROJString(formatter);
164
3.42k
    }
165
166
0
    void _exportToJSON(io::JSONFormatter *formatter) const override {
167
0
        Transformation::_exportToJSON(formatter);
168
0
    }
169
170
    bool _isEquivalentTo(
171
        const util::IComparable *other,
172
        util::IComparable::Criterion criterion =
173
            util::IComparable::Criterion::STRICT,
174
648
        const io::DatabaseContextPtr &dbContext = nullptr) const override {
175
648
        return InverseCoordinateOperation::_isEquivalentTo(other, criterion,
176
648
                                                           dbContext);
177
648
    }
178
179
1.18k
    CoordinateOperationNNPtr inverse() const override {
180
1.18k
        return InverseCoordinateOperation::inverse();
181
1.18k
    }
182
183
    TransformationNNPtr inverseAsTransformation() const;
184
185
#ifdef _MSC_VER
186
    // To avoid a warning C4250:
187
    // 'osgeo::proj::operation::InverseTransformation': inherits
188
    // 'osgeo::proj::operation::SingleOperation::osgeo::proj::operation::SingleOperation::gridsNeeded'
189
    // via dominance
190
    std::set<GridDescription>
191
    gridsNeeded(const io::DatabaseContextPtr &databaseContext,
192
                bool considerKnownGridsAsAvailable) const override {
193
        return SingleOperation::gridsNeeded(databaseContext,
194
                                            considerKnownGridsAsAvailable);
195
    }
196
#endif
197
198
    static TransformationNNPtr create(const TransformationNNPtr &forward);
199
200
    CoordinateOperationNNPtr _shallowClone() const override;
201
};
202
203
// ---------------------------------------------------------------------------
204
205
class PROJBasedOperation;
206
/** Shared pointer of PROJBasedOperation */
207
using PROJBasedOperationPtr = std::shared_ptr<PROJBasedOperation>;
208
/** Non-null shared pointer of PROJBasedOperation */
209
using PROJBasedOperationNNPtr = util::nn<PROJBasedOperationPtr>;
210
211
/** \brief A PROJ-string based coordinate operation.
212
 */
213
class PROJBasedOperation : public SingleOperation {
214
  public:
215
    ~PROJBasedOperation() override;
216
217
    void _exportToWKT(io::WKTFormatter *formatter)
218
        const override; // throw(io::FormattingException)
219
220
    CoordinateOperationNNPtr inverse() const override;
221
222
    static PROJBasedOperationNNPtr
223
    create(const util::PropertyMap &properties, const std::string &PROJString,
224
           const crs::CRSPtr &sourceCRS, const crs::CRSPtr &targetCRS,
225
           const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
226
227
    static PROJBasedOperationNNPtr
228
    create(const util::PropertyMap &properties,
229
           const io::IPROJStringExportableNNPtr &projExportable, bool inverse,
230
           const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS,
231
           const crs::CRSPtr &interpolationCRS,
232
           const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies,
233
           bool hasRoughTransformation);
234
235
    std::set<GridDescription>
236
    gridsNeeded(const io::DatabaseContextPtr &databaseContext,
237
                bool considerKnownGridsAsAvailable) const override;
238
239
  protected:
240
3.38k
    PROJBasedOperation(const PROJBasedOperation &) = default;
241
    explicit PROJBasedOperation(const OperationMethodNNPtr &methodIn);
242
243
    void _exportToPROJString(io::PROJStringFormatter *formatter)
244
        const override; // throw(FormattingException)
245
246
    void _exportToJSON(io::JSONFormatter *formatter)
247
        const override; // throw(FormattingException)
248
249
    CoordinateOperationNNPtr _shallowClone() const override;
250
251
    INLINED_MAKE_SHARED
252
253
  private:
254
    std::string projString_{};
255
    io::IPROJStringExportablePtr projStringExportable_{};
256
    bool inverse_ = false;
257
};
258
259
// ---------------------------------------------------------------------------
260
261
class InvalidOperationEmptyIntersection : public InvalidOperation {
262
  public:
263
    explicit InvalidOperationEmptyIntersection(const std::string &message);
264
    InvalidOperationEmptyIntersection(
265
        const InvalidOperationEmptyIntersection &other);
266
    ~InvalidOperationEmptyIntersection() override;
267
};
268
} // namespace operation
269
270
NS_PROJ_END
271
272
//! @endcond
273
274
#endif // COORDINATEOPERATION_INTERNAL_HH_INCLUDED