Line data Source code
1 : ///////////////////////////////////////////////////////////////////////////////
2 : //
3 : // Project: C++ Test Suite for GDAL/OGR
4 : // Purpose: Main program of C++ Unit Tests runner for GDAL
5 : // Author: Mateusz Loskot <mateusz@loskot.net>
6 : //
7 : ///////////////////////////////////////////////////////////////////////////////
8 : // Copyright (c) 2006, Mateusz Loskot <mateusz@loskot.net>
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 : #ifdef _MSC_VER
30 : #define WIN32_LEAN_AND_MEAN
31 : #endif // _MSC_VER
32 :
33 : #include "gdal_unit_test.h"
34 :
35 : #include "cpl_conv.h"
36 : #include "cpl_multiproc.h"
37 : #include "gdal.h"
38 : #include "ogr_api.h"
39 : #include "ogrsf_frmts.h"
40 : #include "test_data.h"
41 :
42 : #include <algorithm>
43 : #include <iostream>
44 : #include <string>
45 :
46 : #include "gtest_include.h"
47 :
48 : namespace tut
49 : {
50 : // Common test data path
51 : std::string const common::data_basedir(TUT_ROOT_DATA_DIR);
52 : std::string const common::tmp_basedir(TUT_ROOT_TMP_DIR);
53 :
54 : ::testing::AssertionResult
55 34 : CheckEqualGeometries(OGRGeometryH lhs, OGRGeometryH rhs, double tolerance)
56 : {
57 : // Test raw pointers
58 34 : if (nullptr == lhs)
59 : {
60 0 : return ::testing::AssertionFailure() << "lhs is null";
61 : }
62 34 : if (nullptr == rhs)
63 : {
64 0 : return ::testing::AssertionFailure() << "rhs is null";
65 : }
66 :
67 : // Test basic properties
68 34 : if (strcmp(OGR_G_GetGeometryName(lhs), OGR_G_GetGeometryName(rhs)) != 0)
69 : {
70 0 : return ::testing::AssertionFailure()
71 0 : << "OGR_G_GetGeometryName(lhs) = " << OGR_G_GetGeometryName(lhs)
72 0 : << ". OGR_G_GetGeometryName(rhs) = "
73 0 : << OGR_G_GetGeometryName(rhs);
74 : }
75 :
76 34 : if (OGR_G_GetGeometryCount(lhs) != OGR_G_GetGeometryCount(rhs))
77 : {
78 0 : return ::testing::AssertionFailure()
79 0 : << "OGR_G_GetGeometryCount(lhs) = "
80 0 : << OGR_G_GetGeometryCount(lhs)
81 0 : << ". OGR_G_GetGeometryCount(rhs) = "
82 0 : << OGR_G_GetGeometryCount(rhs);
83 : }
84 :
85 34 : if (OGR_G_GetPointCount(lhs) != OGR_G_GetPointCount(rhs))
86 : {
87 0 : return ::testing::AssertionFailure()
88 0 : << "OGR_G_GetPointCount(lhs) = " << OGR_G_GetPointCount(lhs)
89 0 : << ". OGR_G_GetPointCount(rhs) = " << OGR_G_GetPointCount(rhs);
90 : }
91 :
92 34 : if (OGR_G_GetGeometryCount(lhs) > 0)
93 : {
94 : // Test sub-geometries recursively
95 17 : const int count = OGR_G_GetGeometryCount(lhs);
96 36 : for (int i = 0; i < count; ++i)
97 : {
98 : auto res =
99 : CheckEqualGeometries(OGR_G_GetGeometryRef(lhs, i),
100 19 : OGR_G_GetGeometryRef(rhs, i), tolerance);
101 19 : if (!res)
102 0 : return res;
103 : }
104 : }
105 : else
106 : {
107 0 : std::unique_ptr<OGRGeometry> lhs_normalized_cpp;
108 0 : std::unique_ptr<OGRGeometry> rhs_normalized_cpp;
109 17 : if (EQUAL(OGR_G_GetGeometryName(lhs), "LINEARRING"))
110 : {
111 : // Normalize() doesn't work with LinearRing
112 : OGRLineString lhs_as_ls(
113 30 : *OGRGeometry::FromHandle(lhs)->toLineString());
114 15 : lhs_normalized_cpp.reset(lhs_as_ls.Normalize());
115 : OGRLineString rhs_as_ls(
116 30 : *OGRGeometry::FromHandle(rhs)->toLineString());
117 15 : rhs_normalized_cpp.reset(rhs_as_ls.Normalize());
118 : }
119 : else
120 : {
121 2 : lhs_normalized_cpp.reset(
122 : OGRGeometry::FromHandle(OGR_G_Normalize(lhs)));
123 2 : rhs_normalized_cpp.reset(
124 : OGRGeometry::FromHandle(OGR_G_Normalize(rhs)));
125 : }
126 17 : auto lhs_normalized = OGRGeometry::ToHandle(lhs_normalized_cpp.get());
127 17 : auto rhs_normalized = OGRGeometry::ToHandle(rhs_normalized_cpp.get());
128 :
129 : // Test geometry points
130 17 : const std::size_t csize = 3;
131 17 : double a[csize] = {0};
132 17 : double b[csize] = {0};
133 17 : double d[csize] = {0};
134 17 : double dmax = 0;
135 :
136 17 : const int count = OGR_G_GetPointCount(lhs_normalized);
137 285 : for (int i = 0; i < count; ++i)
138 : {
139 268 : OGR_G_GetPoint(lhs_normalized, i, &a[0], &a[1], &a[2]);
140 268 : OGR_G_GetPoint(rhs_normalized, i, &b[0], &b[1], &b[2]);
141 :
142 : // Test vertices
143 1072 : for (std::size_t c = 0; c < csize; ++c)
144 : {
145 804 : d[c] = std::fabs(a[c] - b[c]);
146 : }
147 :
148 268 : const double *pos = std::max_element(d, d + csize);
149 268 : dmax = *pos;
150 :
151 268 : if (dmax > tolerance)
152 : {
153 0 : return ::testing::AssertionFailure()
154 0 : << "dmax = " << dmax << " is > tolerance = " << tolerance
155 0 : << " on vertex " << i;
156 : }
157 : }
158 : }
159 :
160 34 : return ::testing::AssertionSuccess();
161 : }
162 :
163 : } // namespace tut
164 :
165 1 : int main(int argc, char *argv[])
166 : {
167 : #if defined(PROJ_GRIDS_PATH) && defined(PROJ_DB_TMPDIR)
168 : // Look for proj.db in PROJ search paths, copy it in PROJ_DB_TMPDIR, and restrict
169 : // PROJ search paths to PROJ_DB_TMPDIR and PROJ_GRIDS_PATH
170 1 : VSIMkdir(PROJ_DB_TMPDIR, 0755);
171 : static char szProjNetworkOff[] = "PROJ_NETWORK=OFF";
172 1 : putenv(szProjNetworkOff);
173 1 : const CPLStringList aosPathsOri(OSRGetPROJSearchPaths());
174 1 : bool bFoundProjDB = false;
175 1 : for (int i = 0; i < aosPathsOri.size(); ++i)
176 : {
177 : VSIStatBufL sStat;
178 1 : if (VSIStatL(CPLFormFilename(aosPathsOri[i], "proj.db", nullptr),
179 1 : &sStat) == 0)
180 : {
181 1 : CPLCopyFile(CPLFormFilename(PROJ_DB_TMPDIR, "proj.db", nullptr),
182 : CPLFormFilename(aosPathsOri[i], "proj.db", nullptr));
183 1 : bFoundProjDB = true;
184 1 : break;
185 : }
186 : }
187 1 : if (bFoundProjDB)
188 : {
189 2 : CPLStringList aosPaths;
190 1 : aosPaths.AddString(PROJ_DB_TMPDIR);
191 1 : aosPaths.AddString(PROJ_GRIDS_PATH);
192 1 : OSRSetPROJSearchPaths(aosPaths.List());
193 : }
194 : #endif
195 :
196 : // Register GDAL/OGR drivers
197 1 : ::GDALAllRegister();
198 1 : ::OGRRegisterAll();
199 :
200 : std::cout
201 : << "GDAL C/C++ API tests"
202 : << " (" << ::GDALVersionInfo("--version") << ")"
203 1 : << "\n---------------------------------------------------------\n";
204 :
205 1 : argc = GDALGeneralCmdLineProcessor(argc, &argv, 0);
206 :
207 : int nRetCode;
208 : try
209 : {
210 1 : testing::InitGoogleTest(&argc, argv);
211 :
212 1 : nRetCode = RUN_ALL_TESTS();
213 : }
214 0 : catch (const std::exception &e)
215 : {
216 0 : nRetCode = 1;
217 0 : fprintf(stderr, "Caught exception %s\n", e.what());
218 : }
219 0 : catch (...)
220 : {
221 0 : nRetCode = 1;
222 0 : fprintf(stderr, "Caught exception of unknown type\n");
223 : }
224 :
225 1 : CSLDestroy(argv);
226 1 : GDALDestroyDriverManager();
227 :
228 1 : GDALAllRegister();
229 1 : GDALDestroyDriverManager();
230 :
231 1 : OGRCleanupAll();
232 :
233 1 : CPLDumpSharedList(nullptr);
234 1 : CPLCleanupTLS();
235 :
236 1 : return nRetCode;
237 : }
|