/src/PROJ/src/transformations/tinshift_gpkg.hpp
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * Project: PROJ |
3 | | * Purpose: Functionality related to TIN based transformations using a |
4 | | *GeoPackage file Author: Even Rouault, <even.rouault at spatialys.com> |
5 | | * |
6 | | ****************************************************************************** |
7 | | * Copyright (c) 2025, Even Rouault, <even.rouault at spatialys.com> |
8 | | * |
9 | | * SPDX-License-Identifier: MIT |
10 | | *****************************************************************************/ |
11 | | |
12 | | #ifndef TINSHIFT_GEOPACKAGE_H |
13 | | #define TINSHIFT_GEOPACKAGE_H |
14 | | |
15 | | #include <array> |
16 | | #include <exception> |
17 | | #include <memory> |
18 | | #include <string> |
19 | | #include <vector> |
20 | | |
21 | | #include "sqlite3_utils.hpp" |
22 | | #include "tinshift_iface.hpp" |
23 | | |
24 | | struct sqlite3; |
25 | | struct sqlite3_stmt; |
26 | | |
27 | | // --------------------------------------------------------------------------- |
28 | | |
29 | | class TINShiftGeopackageException : public std::exception { |
30 | | public: |
31 | 0 | explicit TINShiftGeopackageException(const std::string &msg) : msg_(msg) {} |
32 | | const char *what() const noexcept override; |
33 | | |
34 | | private: |
35 | | std::string msg_; |
36 | | }; |
37 | | |
38 | | // --------------------------------------------------------------------------- |
39 | | |
40 | | class TINShiftGeopackageFile { |
41 | | public: |
42 | | /** Open the provided GeoPackage and return an object. |
43 | | * |
44 | | * @throws TINShiftGeopackageException in case of error. |
45 | | */ |
46 | | static std::unique_ptr<TINShiftGeopackageFile> |
47 | | open(PJ_CONTEXT *ctx, const std::string &filename); |
48 | | |
49 | | /** Destructor */ |
50 | | ~TINShiftGeopackageFile(); |
51 | | |
52 | | /** Find the triangle into which (x, y) is located */ |
53 | | bool findTriangle(double x, double y, bool forwardDirection, |
54 | | double &lambda1, double &lambda2, double &lambda3, |
55 | | std::vector<double> &valsVertex1, |
56 | | std::vector<double> &valsVertex2, |
57 | | std::vector<double> &valsVertex3); |
58 | | |
59 | 0 | bool hasHorizontalTransformation() const { |
60 | 0 | return horizontalTransformation_; |
61 | 0 | } |
62 | 0 | bool hasVerticalTransformation() const { return verticalTransformation_; } |
63 | 0 | bool hasOffsetZ() const { return offsetZ_; } |
64 | | |
65 | | private: |
66 | | std::unique_ptr<NS_PROJ::SQLite3VFS> sqlite_vfs_{}; |
67 | | sqlite3 *sqlite_handle_ = nullptr; |
68 | | sqlite3_stmt *select_stmt_ = nullptr; |
69 | | std::vector<std::string> vertices_cols_{}; |
70 | | int numVertices_ = 0; |
71 | | bool horizontalTransformation_ = false; |
72 | | bool verticalTransformation_ = false; |
73 | | bool sourceZ_ = false; |
74 | | bool targetX_ = false; |
75 | | bool targetY_ = false; |
76 | | bool targetZ_ = false; |
77 | | bool offsetZ_ = false; |
78 | | double min_x_ = 0; |
79 | | double min_y_ = 0; |
80 | | double max_x_ = 0; |
81 | | double max_y_ = 0; |
82 | | double min_shift_x_ = 0; |
83 | | double min_shift_y_ = 0; |
84 | | double max_shift_x_ = 0; |
85 | | double max_shift_y_ = 0; |
86 | | |
87 | | enum FallbackStrategy { |
88 | | FALLBACK_NONE, |
89 | | FALLBACK_NEAREST_SIDE, |
90 | | FALLBACK_NEAREST_CENTROID, |
91 | | }; |
92 | | FallbackStrategy fallbackStrategy_ = FALLBACK_NONE; |
93 | | |
94 | | // Cached results |
95 | | bool cachedForwardDirection_ = false; |
96 | | std::array<double, 3> cachedVerticesX_{0, 0, 0}; |
97 | | std::array<double, 3> cachedVerticesY_{0, 0, 0}; |
98 | | std::vector<double> cachedValsVertex1_{}; |
99 | | std::vector<double> cachedValsVertex2_{}; |
100 | | std::vector<double> cachedValsVertex3_{}; |
101 | | |
102 | | private: |
103 | 0 | TINShiftGeopackageFile() = default; |
104 | | TINShiftGeopackageFile(const TINShiftGeopackageFile &) = delete; |
105 | | TINShiftGeopackageFile &operator=(const TINShiftGeopackageFile &) = delete; |
106 | | |
107 | | void getMetadata(); |
108 | | void prepareDatabaseQuery(); |
109 | | }; |
110 | | |
111 | | // --------------------------------------------------------------------------- |
112 | | |
113 | | /** Class to evaluate the transformation of a coordinate */ |
114 | | class TINShiftGeopackageEvaluator : public TINShiftEvaluator { |
115 | | public: |
116 | | /** Constructor. */ |
117 | | explicit TINShiftGeopackageEvaluator( |
118 | | std::unique_ptr<TINShiftGeopackageFile> fileIn); |
119 | | |
120 | | bool forward(double x, double y, double z, double &x_out, double &y_out, |
121 | | double &z_out) override; |
122 | | |
123 | | bool inverse(double x, double y, double z, double &x_out, double &y_out, |
124 | | double &z_out) override; |
125 | | |
126 | | private: |
127 | | std::unique_ptr<TINShiftGeopackageFile> file_; |
128 | | |
129 | | bool transform(bool forwardDirection, double x, double y, double z, |
130 | | double &x_out, double &y_out, double &z_out); |
131 | | }; |
132 | | |
133 | | // --------------------------------------------------------------------------- |
134 | | |
135 | | #endif |