Line data Source code
1 : ///////////////////////////////////////////////////////////////////////////////
2 : //
3 : // Project: C++ Test Suite for GDAL/OGR
4 : // Purpose: Test ogr_wkb.h
5 : // Author: Even Rouault <even.rouault at spatialys.com>
6 : //
7 : ///////////////////////////////////////////////////////////////////////////////
8 : // Copyright (c) 2023, Even Rouault <even.rouault at spatialys.com>
9 : /*
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #include "gdal_unit_test.h"
14 :
15 : #include "ogr_geometry.h"
16 : #include "ogr_wkb.h"
17 :
18 : #include "gtest_include.h"
19 :
20 : #include <limits>
21 :
22 : namespace
23 : {
24 :
25 : struct test_ogr_wkb : public ::testing::Test
26 : {
27 : };
28 :
29 : class OGRWKBGetEnvelopeFixture
30 : : public test_ogr_wkb,
31 : public ::testing::WithParamInterface<std::tuple<
32 : const char *, double, double, double, double, const char *>>
33 : {
34 : static constexpr double INF = std::numeric_limits<double>::infinity();
35 :
36 : public:
37 : static std::vector<
38 : std::tuple<const char *, double, double, double, double, const char *>>
39 1 : GetTupleValues()
40 : {
41 : return {
42 : std::make_tuple("POINT(1 2)", 1, 2, 1, 2, "POINT"),
43 : std::make_tuple("POINT EMPTY", INF, INF, -INF, -INF, "POINT_EMPTY"),
44 : std::make_tuple("POINT Z (1 2 3)", 1, 2, 1, 2, "POINT_3D"),
45 : std::make_tuple("LINESTRING(3 4,1 2)", 1, 2, 3, 4, "LINESTRING"),
46 : std::make_tuple("LINESTRING EMPTY", INF, INF, -INF, -INF,
47 : "LINESTRING_EMPTY"),
48 : std::make_tuple("LINESTRING Z (3 4 5,1 2 6)", 1, 2, 3, 4,
49 : "LINESTRING_3D"),
50 : std::make_tuple("POLYGON((0 1,0 2,3 2,0 1))", 0, 1, 3, 2,
51 : "POLYGON"),
52 : std::make_tuple("POLYGON EMPTY", INF, INF, -INF, -INF,
53 : "POLYGON_EMPTY"),
54 : std::make_tuple("POLYGON Z ((0 1 10,0 2 20,3 2 20,0 1 10))", 0, 1,
55 : 3, 2, "POLYGON_3D"),
56 : std::make_tuple("MULTIPOINT((1 2),(3 4))", 1, 2, 3, 4,
57 : "MULTIPOINT"),
58 : std::make_tuple("MULTIPOINT EMPTY", INF, INF, -INF, -INF,
59 : "MULTIPOINT_EMPTY"),
60 : std::make_tuple("MULTIPOINT Z ((1 2 10),(3 4 20))", 1, 2, 3, 4,
61 : "MULTIPOINT_3D"),
62 : std::make_tuple("MULTILINESTRING((3 4,1 2),(5 6,7 8))", 1, 2, 7, 8,
63 : "MULTILINESTRING"),
64 : std::make_tuple("MULTILINESTRING EMPTY", INF, INF, -INF, -INF,
65 : "MULTILINESTRING_EMPTY"),
66 : std::make_tuple(
67 : "MULTILINESTRING Z ((3 4 10,1 2 20),(5 6 10,7 8 20))", 1, 2, 7,
68 : 8, "MULTILINESTRING_3D"),
69 : std::make_tuple(
70 : "MULTIPOLYGON(((0 1,0 2,3 2,0 1)),((0 -1,0 -2,-3 -2,0 -1)))",
71 : -3, -2, 3, 2, "MULTIPOLYGON"),
72 : std::make_tuple("MULTIPOLYGON EMPTY", INF, INF, -INF, -INF,
73 : "MULTIPOLYGON_EMPTY"),
74 : std::make_tuple("MULTIPOLYGON Z (((0 1 10,0 2 20,3 2 20,0 1 "
75 : "10)),((0 -1 -10,0 -2 -20,-3 -2 -20,0 -1 -10)))",
76 : -3, -2, 3, 2, "MULTIPOLYGON_3D"),
77 : std::make_tuple("GEOMETRYCOLLECTION(POINT(1 2),POINT(3 4))", 1, 2,
78 : 3, 4, "GEOMETRYCOLLECTION"),
79 : std::make_tuple("CIRCULARSTRING(0 10,1 11,2 10)", 0, 10, 2, 11,
80 : "CIRCULARSTRING"),
81 : std::make_tuple("COMPOUNDCURVE((3 4,1 2))", 1, 2, 3, 4,
82 : "COMPOUNDCURVE"),
83 : std::make_tuple("CURVEPOLYGON((0 1,0 2,3 2,0 1))", 0, 1, 3, 2,
84 : "CURVEPOLYGON"),
85 : std::make_tuple("MULTICURVE((3 4,1 2),(5 6,7 8))", 1, 2, 7, 8,
86 : "MULTICURVE"),
87 : std::make_tuple(
88 : "MULTISURFACE(((0 1,0 2,3 2,0 1)),((0 -1,0 -2,-3 -2,0 -1)))",
89 : -3, -2, 3, 2, "MULTISURFACE"),
90 : std::make_tuple("TRIANGLE((0 1,0 2,3 2,0 1))", 0, 1, 3, 2,
91 : "TRIANGLE"),
92 : std::make_tuple("POLYHEDRALSURFACE(((0 1,0 2,3 2,0 1)))", 0, 1, 3,
93 : 2, "POLYHEDRALSURFACE"),
94 : std::make_tuple("TIN(((0 1,0 2,3 2,0 1)))", 0, 1, 3, 2, "TIN"),
95 1 : };
96 : }
97 : };
98 :
99 55 : TEST_P(OGRWKBGetEnvelopeFixture, test)
100 : {
101 27 : const char *pszInput = std::get<0>(GetParam());
102 27 : const double dfExpectedMinX = std::get<1>(GetParam());
103 27 : const double dfExpectedMinY = std::get<2>(GetParam());
104 27 : const double dfExpectedMaxX = std::get<3>(GetParam());
105 27 : const double dfExpectedMaxY = std::get<4>(GetParam());
106 :
107 27 : OGRGeometry *poGeom = nullptr;
108 27 : ASSERT_EQ(OGRGeometryFactory::createFromWkt(pszInput, nullptr, &poGeom),
109 : OGRERR_NONE);
110 27 : ASSERT_TRUE(poGeom != nullptr);
111 54 : std::vector<GByte> abyWkb(poGeom->WkbSize());
112 27 : poGeom->exportToWkb(wkbNDR, abyWkb.data(), wkbVariantIso);
113 27 : delete poGeom;
114 27 : OGREnvelope sEnvelope;
115 27 : EXPECT_EQ(OGRWKBGetBoundingBox(abyWkb.data(), abyWkb.size(), sEnvelope),
116 : true);
117 27 : EXPECT_EQ(sEnvelope.MinX, dfExpectedMinX);
118 27 : EXPECT_EQ(sEnvelope.MinY, dfExpectedMinY);
119 27 : EXPECT_EQ(sEnvelope.MaxX, dfExpectedMaxX);
120 27 : EXPECT_EQ(sEnvelope.MaxY, dfExpectedMaxY);
121 : }
122 :
123 56 : INSTANTIATE_TEST_SUITE_P(
124 : test_ogr_wkb, OGRWKBGetEnvelopeFixture,
125 : ::testing::ValuesIn(OGRWKBGetEnvelopeFixture::GetTupleValues()),
126 : [](const ::testing::TestParamInfo<OGRWKBGetEnvelopeFixture::ParamType>
127 : &l_info) { return std::get<5>(l_info.param); });
128 :
129 : class OGRWKBGetEnvelope3DFixture
130 : : public test_ogr_wkb,
131 : public ::testing::WithParamInterface<
132 : std::tuple<const char *, double, double, double, double, double,
133 : double, const char *>>
134 : {
135 : static constexpr double INF = std::numeric_limits<double>::infinity();
136 :
137 : public:
138 : static std::vector<std::tuple<const char *, double, double, double, double,
139 : double, double, const char *>>
140 1 : GetTupleValues()
141 : {
142 : return {
143 : std::make_tuple("POINT(1 2)", 1, 2, INF, 1, 2, -INF, "POINT"),
144 : std::make_tuple("POINT EMPTY", INF, INF, INF, -INF, -INF, -INF,
145 : "POINT_EMPTY"),
146 : std::make_tuple("POINT Z (1 2 3)", 1, 2, 3, 1, 2, 3, "POINT_3D"),
147 : std::make_tuple("LINESTRING(3 4,1 2)", 1, 2, INF, 3, 4, -INF,
148 : "LINESTRING"),
149 : std::make_tuple("LINESTRING EMPTY", INF, INF, INF, -INF, -INF, -INF,
150 : "LINESTRING_EMPTY"),
151 : std::make_tuple("LINESTRING Z (3 4 5,1 2 6)", 1, 2, 5, 3, 4, 6,
152 : "LINESTRING_3D"),
153 : std::make_tuple("POLYGON((0 1,0 2,3 2,0 1))", 0, 1, INF, 3, 2, -INF,
154 : "POLYGON"),
155 : std::make_tuple("POLYGON EMPTY", INF, INF, INF, -INF, -INF, -INF,
156 : "POLYGON_EMPTY"),
157 : std::make_tuple("POLYGON Z ((0 1 10,0 2 20,3 2 20,0 1 10))", 0, 1,
158 : 10, 3, 2, 20, "POLYGON_3D"),
159 : std::make_tuple("MULTIPOINT((1 2),(3 4))", 1, 2, INF, 3, 4, -INF,
160 : "MULTIPOINT"),
161 : std::make_tuple("MULTIPOINT EMPTY", INF, INF, INF, -INF, -INF, -INF,
162 : "MULTIPOINT_EMPTY"),
163 : std::make_tuple("MULTIPOINT Z ((1 2 10),(3 4 20))", 1, 2, 10, 3, 4,
164 : 20, "MULTIPOINT_3D"),
165 : std::make_tuple("MULTILINESTRING((3 4,1 2),(5 6,7 8))", 1, 2, INF,
166 : 7, 8, -INF, "MULTILINESTRING"),
167 : std::make_tuple("MULTILINESTRING EMPTY", INF, INF, INF, -INF, -INF,
168 : -INF, "MULTILINESTRING_EMPTY"),
169 : std::make_tuple(
170 : "MULTILINESTRING Z ((3 4 10,1 2 20),(5 6 10,7 8 20))", 1, 2, 10,
171 : 7, 8, 20, "MULTILINESTRING_3D"),
172 : std::make_tuple(
173 : "MULTIPOLYGON(((0 1,0 2,3 2,0 1)),((0 -1,0 -2,-3 -2,0 -1)))",
174 : -3, -2, INF, 3, 2, -INF, "MULTIPOLYGON"),
175 : std::make_tuple("MULTIPOLYGON EMPTY", INF, INF, INF, -INF, -INF,
176 : -INF, "MULTIPOLYGON_EMPTY"),
177 : std::make_tuple("MULTIPOLYGON Z (((0 1 10,0 2 20,3 2 20,0 1 "
178 : "10)),((0 -1 -10,0 -2 -20,-3 -2 -20,0 -1 -10)))",
179 : -3, -2, -20, 3, 2, 20, "MULTIPOLYGON_3D"),
180 1 : };
181 : }
182 : };
183 :
184 37 : TEST_P(OGRWKBGetEnvelope3DFixture, test)
185 : {
186 18 : const char *pszInput = std::get<0>(GetParam());
187 18 : const double dfExpectedMinX = std::get<1>(GetParam());
188 18 : const double dfExpectedMinY = std::get<2>(GetParam());
189 18 : const double dfExpectedMinZ = std::get<3>(GetParam());
190 18 : const double dfExpectedMaxX = std::get<4>(GetParam());
191 18 : const double dfExpectedMaxY = std::get<5>(GetParam());
192 18 : const double dfExpectedMaxZ = std::get<6>(GetParam());
193 :
194 18 : OGRGeometry *poGeom = nullptr;
195 18 : ASSERT_EQ(OGRGeometryFactory::createFromWkt(pszInput, nullptr, &poGeom),
196 : OGRERR_NONE);
197 18 : ASSERT_TRUE(poGeom != nullptr);
198 36 : std::vector<GByte> abyWkb(poGeom->WkbSize());
199 18 : poGeom->exportToWkb(wkbNDR, abyWkb.data(), wkbVariantIso);
200 18 : delete poGeom;
201 18 : OGREnvelope3D sEnvelope;
202 18 : EXPECT_EQ(OGRWKBGetBoundingBox(abyWkb.data(), abyWkb.size(), sEnvelope),
203 : true);
204 18 : EXPECT_EQ(sEnvelope.MinX, dfExpectedMinX);
205 18 : EXPECT_EQ(sEnvelope.MinY, dfExpectedMinY);
206 18 : EXPECT_EQ(sEnvelope.MinZ, dfExpectedMinZ);
207 18 : EXPECT_EQ(sEnvelope.MaxX, dfExpectedMaxX);
208 18 : EXPECT_EQ(sEnvelope.MaxY, dfExpectedMaxY);
209 18 : EXPECT_EQ(sEnvelope.MaxZ, dfExpectedMaxZ);
210 : }
211 :
212 38 : INSTANTIATE_TEST_SUITE_P(
213 : test_ogr_wkb, OGRWKBGetEnvelope3DFixture,
214 : ::testing::ValuesIn(OGRWKBGetEnvelope3DFixture::GetTupleValues()),
215 : [](const ::testing::TestParamInfo<OGRWKBGetEnvelope3DFixture::ParamType>
216 : &l_info) { return std::get<7>(l_info.param); });
217 :
218 : class OGRWKBFixupCounterClockWiseExternalRingFixture
219 : : public test_ogr_wkb,
220 : public ::testing::WithParamInterface<
221 : std::tuple<const char *, const char *, const char *>>
222 : {
223 : public:
224 : static std::vector<std::tuple<const char *, const char *, const char *>>
225 1 : GetTupleValues()
226 : {
227 : return {
228 : std::make_tuple("MULTIPOLYGON (((0 1,0 0,1 1,0 1),(0.2 0.3,0.2 "
229 : "0.8,0.7 0.8,0.2 0.3)))",
230 : "MULTIPOLYGON (((0 1,0 0,1 1,0 1),(0.2 0.3,0.2 "
231 : "0.8,0.7 0.8,0.2 0.3)))",
232 : "MULTIPOLYGON_CCW"),
233 : std::make_tuple("MULTIPOLYGON (((1 1,0 0,0 1,1 1),(0.2 0.3,0.7 "
234 : "0.8,0.2 0.8,0.2 0.3)))",
235 : "MULTIPOLYGON (((1 1,0 1,0 0,1 1),(0.2 0.3,0.2 "
236 : "0.8,0.7 0.8,0.2 0.3)))",
237 : "MULTIPOLYGON_CW"),
238 : std::make_tuple(
239 : "MULTIPOLYGON Z (((0 0 10,0 1 10,1 1 10,0 0 10),(0.2 0.3 "
240 : "10,0.7 0.8 10,0.2 0.8 10,0.2 0.3 10)))",
241 : "MULTIPOLYGON Z (((0 0 10,1 1 10,0 1 10,0 0 10),(0.2 0.3 "
242 : "10,0.2 0.8 10,0.7 0.8 10,0.2 0.3 10)))",
243 : "MULTIPOLYGON_CW_3D"),
244 : std::make_tuple("MULTIPOLYGON (((0 0,0 0,1 1,1 1,0 1,0 1,0 0)))",
245 : "MULTIPOLYGON (((0 0,0 0,1 1,1 1,0 1,0 1,0 0)))",
246 : "MULTIPOLYGON_CCW_REPEATED_POINTS"),
247 : std::make_tuple("MULTIPOLYGON (((0 0,0 0,0 1,0 1,1 1,1 1,0 0)))",
248 : "MULTIPOLYGON (((0 0,1 1,1 1,0 1,0 1,0 0,0 0)))",
249 : "MULTIPOLYGON_CW_REPEATED_POINTS"),
250 : std::make_tuple("MULTIPOLYGON EMPTY", "MULTIPOLYGON EMPTY",
251 : "MULTIPOLYGON_EMPTY"),
252 : std::make_tuple("POINT (1 2)", "POINT (1 2)", "POINT"),
253 1 : };
254 : }
255 : };
256 :
257 15 : TEST_P(OGRWKBFixupCounterClockWiseExternalRingFixture, test)
258 : {
259 7 : const char *pszInput = std::get<0>(GetParam());
260 7 : const char *pszExpected = std::get<1>(GetParam());
261 :
262 7 : OGRGeometry *poGeom = nullptr;
263 7 : ASSERT_EQ(OGRGeometryFactory::createFromWkt(pszInput, nullptr, &poGeom),
264 : OGRERR_NONE);
265 7 : ASSERT_TRUE(poGeom != nullptr);
266 7 : std::vector<GByte> abyWkb(poGeom->WkbSize());
267 7 : poGeom->exportToWkb(wkbNDR, abyWkb.data());
268 7 : OGRWKBFixupCounterClockWiseExternalRing(abyWkb.data(), abyWkb.size());
269 7 : delete poGeom;
270 7 : poGeom = nullptr;
271 7 : OGRGeometryFactory::createFromWkb(abyWkb.data(), nullptr, &poGeom);
272 7 : ASSERT_TRUE(poGeom != nullptr);
273 7 : char *pszWKT = nullptr;
274 7 : poGeom->exportToWkt(&pszWKT, wkbVariantIso);
275 7 : EXPECT_STREQ(pszWKT, pszExpected);
276 7 : CPLFree(pszWKT);
277 7 : delete poGeom;
278 : }
279 :
280 16 : INSTANTIATE_TEST_SUITE_P(
281 : test_ogr_wkb, OGRWKBFixupCounterClockWiseExternalRingFixture,
282 : ::testing::ValuesIn(
283 : OGRWKBFixupCounterClockWiseExternalRingFixture::GetTupleValues()),
284 : [](const ::testing::TestParamInfo<
285 : OGRWKBFixupCounterClockWiseExternalRingFixture::ParamType> &l_info)
286 : { return std::get<2>(l_info.param); });
287 :
288 : class OGRWKBIntersectsPessimisticFixture
289 : : public test_ogr_wkb,
290 : public ::testing::WithParamInterface<std::tuple<
291 : const char *, double, double, double, double, bool, const char *>>
292 : {
293 : public:
294 : static std::vector<std::tuple<const char *, double, double, double, double,
295 : bool, const char *>>
296 1 : GetTupleValues()
297 : {
298 : return {
299 : std::make_tuple("POINT(1 2)", 0.9, 1.9, 1.1, 2.1, true, "POINT_IN"),
300 : std::make_tuple("POINT(1 2)", 1.05, 1.9, 1.1, 2.1, false,
301 : "POINT_OUT1"),
302 : std::make_tuple("POINT(1 2)", 0.9, 2.05, 1.1, 2.1, false,
303 : "POINT_OUT2"),
304 : std::make_tuple("POINT(1 2)", 0.9, 1.9, 0.95, 2.1, false,
305 : "POINT_OUT3"),
306 : std::make_tuple("POINT(1 2)", 0.9, 1.9, 1.1, 1.95, false,
307 : "POINT_OUT4"),
308 : std::make_tuple("POINT Z (1 2 3)", 0.9, 1.9, 1.1, 2.1, true,
309 : "POINTZ_IN"),
310 : std::make_tuple("POINT Z (1 2 3)", 1.05, 1.9, 1.1, 2.1, false,
311 : "POINTZ_OUT"),
312 : std::make_tuple("POINT EMPTY", 0.9, 1.9, 1.1, 2.1, false,
313 : "POINT_EMPTY"),
314 : std::make_tuple("LINESTRING(1 2, 3 4)", 0.9, 1.9, 1.1, 2.1, true,
315 : "LINESTRING_IN"),
316 : std::make_tuple("LINESTRING(1 2, 3 4)", 0.9, 1.9, 0.95, 2.1, false,
317 : "LINESTRING_OUT"),
318 : std::make_tuple("LINESTRING EMPTY", 0.9, 1.9, 1.1, 2.1, false,
319 : "LINESTRING_EMPTY"),
320 : std::make_tuple("LINESTRING Z (1 2 10, 3 4 10)", 0.9, 1.9, 1.1, 2.1,
321 : true, "LINESTRINGZ_IN"),
322 : std::make_tuple("LINESTRING Z (1 2 10, 3 4 10)", 0.9, 1.9, 0.95,
323 : 2.1, false, "LINESTRINGZ_OUT"),
324 : std::make_tuple("POLYGON((1 2,1 3,10 3,1 2))", 0.9, 1.9, 1.1, 2.1,
325 : true, "POLYGON_IN"),
326 : std::make_tuple("POLYGON((1 2,1 3,10 3,1 2))", 0.9, 1.9, 0.95, 2.1,
327 : false, "POLYGON_OUT"),
328 : std::make_tuple("POLYGON EMPTY", 0.9, 1.9, 1.1, 2.1, false,
329 : "POLYGON_EMPTY"),
330 : std::make_tuple("POLYGON Z ((1 2 -10,1 3 -10,10 3 -10,1 2 -10))",
331 : 0.9, 1.9, 1.1, 2.1, true, "POLYGONZ_IN"),
332 : std::make_tuple("POLYGON Z ((1 2 -10,1 3 -10,10 3 -10,1 2 -10))",
333 : 0.9, 1.9, 0.95, 2.1, false, "POLYGONZ_OUT"),
334 : std::make_tuple("MULTIPOINT((1 2))", 0.9, 1.9, 1.1, 2.1, true,
335 : "MULTIPOINT_IN"),
336 : std::make_tuple("MULTIPOINT((1 2))", 1.05, 1.9, 1.1, 2.1, false,
337 : "MULTIPOINT_OUT1"),
338 : std::make_tuple("MULTIPOINT((1 2))", 0.9, 2.05, 1.1, 2.1, false,
339 : "MULTIPOINT_OUT2"),
340 : std::make_tuple("MULTIPOINT((1 2))", 0.9, 1.9, 0.95, 2.1, false,
341 : "MULTIPOINT_OUT3"),
342 : std::make_tuple("MULTIPOINT((1 2))", 0.9, 1.9, 1.1, 1.95, false,
343 : "MULTIPOINT_OUT4"),
344 : std::make_tuple("MULTIPOINT Z ((1 2 3))", 0.9, 1.9, 1.1, 2.1, true,
345 : "MULTIPOINTZ_IN"),
346 : std::make_tuple("MULTIPOINT Z ((1 2 3))", 1.05, 1.9, 1.1, 2.1,
347 : false, "MULTIPOINTZ_OUT"),
348 : std::make_tuple("MULTIPOINT EMPTY", 0.9, 1.9, 1.1, 2.1, false,
349 : "MULTIPOINT_EMPTY"),
350 : std::make_tuple("MULTILINESTRING((1 2, 3 4))", 0.9, 1.9, 1.1, 2.1,
351 : true, "MULTILINESTRING_IN"),
352 : std::make_tuple("MULTILINESTRING((1 2, 3 4))", 0.9, 1.9, 0.95, 2.1,
353 : false, "MULTILINESTRING_OUT"),
354 : std::make_tuple("MULTILINESTRING EMPTY", 0.9, 1.9, 1.1, 2.1, false,
355 : "MULTILINESTRING_EMPTY"),
356 : std::make_tuple("MULTILINESTRING Z ((1 2 10, 3 4 10))", 0.9, 1.9,
357 : 1.1, 2.1, true, "MULTILINESTRINGZ_IN"),
358 : std::make_tuple("MULTILINESTRING Z ((1 2 10, 3 4 10))", 0.9, 1.9,
359 : 0.95, 2.1, false, "MULTILINESTRINGZ_OUT"),
360 : std::make_tuple("MULTIPOLYGON(((1 2,1 3,10 3,1 2)))", 0.9, 1.9, 1.1,
361 : 2.1, true, "MULTIPOLYGON_IN"),
362 : std::make_tuple("MULTIPOLYGON(((1 2,1 3,10 3,1 2)))", 0.9, 1.9,
363 : 0.95, 2.1, false, "MULTIPOLYGON_OUT"),
364 : std::make_tuple("MULTIPOLYGON EMPTY", 0.9, 1.9, 1.1, 2.1, false,
365 : "MULTIPOLYGON_EMPTY"),
366 : std::make_tuple(
367 : "MULTIPOLYGON Z (((1 2 -10,1 3 -10,10 3 -10,1 2 -10)))", 0.9,
368 : 1.9, 1.1, 2.1, true, "MULTIPOLYGONZ_IN"),
369 : std::make_tuple(
370 : "MULTIPOLYGON Z (((1 2 -10,1 3 -10,10 3 -10,1 2 -10)))", 0.9,
371 : 1.9, 0.95, 2.1, false, "MULTIPOLYGONZ_OUT"),
372 : std::make_tuple("GEOMETRYCOLLECTION(POINT(1 2))", 0.9, 1.9, 1.1,
373 : 2.1, true, "GEOMETRYCOLLECTION_POINT_IN"),
374 : std::make_tuple("CIRCULARSTRING(0 10,1 11,2 10)", -0.1, 9.9, 0.1,
375 : 10.1, true, "CIRCULARSTRING_IN"),
376 : std::make_tuple("CIRCULARSTRING(0 10,1 11,2 10)", -0.1, 9.9, -0.05,
377 : 10.1, false, "CIRCULARSTRING_OUT"),
378 : std::make_tuple("CIRCULARSTRING EMPTY", -0.1, 9.9, 0.1, 10.1, false,
379 : "CIRCULARSTRING_EMPTY"),
380 : std::make_tuple("TRIANGLE((1 2,1 3,10 3,1 2))", 0.9, 1.9, 1.1, 2.1,
381 : true, "TRIANGLE_IN"),
382 : std::make_tuple("TRIANGLE((1 2,1 3,10 3,1 2))", 0.9, 1.9, 0.95, 2.1,
383 : false, "TRIANGLE_OUT"),
384 : std::make_tuple("TRIANGLE EMPTY", 0.9, 1.9, 1.1, 2.1, false,
385 : "TRIANGLE_EMPTY"),
386 : std::make_tuple("TRIANGLE Z ((1 2 -10,1 3 -10,10 3 -10,1 2 -10))",
387 : 0.9, 1.9, 1.1, 2.1, true, "TRIANGLEZ_IN"),
388 : std::make_tuple("TRIANGLE Z ((1 2 -10,1 3 -10,10 3 -10,1 2 -10))",
389 : 0.9, 1.9, 0.95, 2.1, false, "TRIANGLEZ_OUT"),
390 : std::make_tuple("COMPOUNDCURVE((1 2, 3 4))", 0.9, 1.9, 1.1, 2.1,
391 : true, "COMPOUNDCURVE_IN"),
392 : std::make_tuple("COMPOUNDCURVE((1 2, 3 4))", 0.9, 1.9, 0.95, 2.1,
393 : false, "COMPOUNDCURVE_OUT"),
394 : std::make_tuple("COMPOUNDCURVE EMPTY", 0.9, 1.9, 1.1, 2.1, false,
395 : "COMPOUNDCURVE_EMPTY"),
396 : std::make_tuple("COMPOUNDCURVE Z ((1 2 10, 3 4 10))", 0.9, 1.9, 1.1,
397 : 2.1, true, "COMPOUNDCURVEZ_IN"),
398 : std::make_tuple("COMPOUNDCURVE Z ((1 2 10, 3 4 10))", 0.9, 1.9,
399 : 0.95, 2.1, false, "COMPOUNDCURVEZ_OUT"),
400 : std::make_tuple("CURVEPOLYGON((1 2,1 3,10 3,1 2))", 0.9, 1.9, 1.1,
401 : 2.1, true, "CURVEPOLYGON_IN"),
402 : std::make_tuple("CURVEPOLYGON((1 2,1 3,10 3,1 2))", 0.9, 1.9, 0.95,
403 : 2.1, false, "CURVEPOLYGON_OUT"),
404 : std::make_tuple("CURVEPOLYGON EMPTY", 0.9, 1.9, 1.1, 2.1, false,
405 : "CURVEPOLYGON_EMPTY"),
406 : std::make_tuple(
407 : "CURVEPOLYGON Z ((1 2 -10,1 3 -10,10 3 -10,1 2 -10))", 0.9, 1.9,
408 : 1.1, 2.1, true, "CURVEPOLYGONZ_IN"),
409 : std::make_tuple(
410 : "CURVEPOLYGON Z ((1 2 -10,1 3 -10,10 3 -10,1 2 -10))", 0.9, 1.9,
411 : 0.95, 2.1, false, "CURVEPOLYGONZ_OUT"),
412 : std::make_tuple("MULTICURVE((1 2, 3 4))", 0.9, 1.9, 1.1, 2.1, true,
413 : "MULTICURVE_IN"),
414 : std::make_tuple("MULTICURVE((1 2, 3 4))", 0.9, 1.9, 0.95, 2.1,
415 : false, "MULTICURVE_OUT"),
416 : std::make_tuple("MULTICURVE EMPTY", 0.9, 1.9, 1.1, 2.1, false,
417 : "MULTICURVE_EMPTY"),
418 : std::make_tuple("MULTICURVE Z ((1 2 10, 3 4 10))", 0.9, 1.9, 1.1,
419 : 2.1, true, "MULTICURVEZ_IN"),
420 : std::make_tuple("MULTICURVE Z ((1 2 10, 3 4 10))", 0.9, 1.9, 0.95,
421 : 2.1, false, "MULTICURVEZ_OUT"),
422 : std::make_tuple("MULTISURFACE(((1 2,1 3,10 3,1 2)))", 0.9, 1.9, 1.1,
423 : 2.1, true, "MULTISURFACE_IN"),
424 : std::make_tuple("MULTISURFACE(((1 2,1 3,10 3,1 2)))", 0.9, 1.9,
425 : 0.95, 2.1, false, "MULTISURFACE_OUT"),
426 : std::make_tuple("MULTISURFACE EMPTY", 0.9, 1.9, 1.1, 2.1, false,
427 : "MULTISURFACE_EMPTY"),
428 : std::make_tuple(
429 : "MULTISURFACE Z (((1 2 -10,1 3 -10,10 3 -10,1 2 -10)))", 0.9,
430 : 1.9, 1.1, 2.1, true, "MULTISURFACEZ_IN"),
431 : std::make_tuple(
432 : "MULTISURFACE Z (((1 2 -10,1 3 -10,10 3 -10,1 2 -10)))", 0.9,
433 : 1.9, 0.95, 2.1, false, "MULTISURFACEZ_OUT"),
434 : std::make_tuple("POLYHEDRALSURFACE(((1 2,1 3,10 3,1 2)))", 0.9, 1.9,
435 : 1.1, 2.1, true, "POLYHEDRALSURFACE_IN"),
436 : std::make_tuple("POLYHEDRALSURFACE(((1 2,1 3,10 3,1 2)))", 0.9, 1.9,
437 : 0.95, 2.1, false, "POLYHEDRALSURFACE_OUT"),
438 : std::make_tuple("POLYHEDRALSURFACE EMPTY", 0.9, 1.9, 1.1, 2.1,
439 : false, "POLYHEDRALSURFACE_EMPTY"),
440 : std::make_tuple(
441 : "POLYHEDRALSURFACE Z (((1 2 -10,1 3 -10,10 3 -10,1 2 -10)))",
442 : 0.9, 1.9, 1.1, 2.1, true, "POLYHEDRALSURFACEZ_IN"),
443 : std::make_tuple(
444 : "POLYHEDRALSURFACE Z (((1 2 -10,1 3 -10,10 3 -10,1 2 -10)))",
445 : 0.9, 1.9, 0.95, 2.1, false, "POLYHEDRALSURFACEZ_OUT"),
446 : std::make_tuple("TIN(((1 2,1 3,10 3,1 2)))", 0.9, 1.9, 1.1, 2.1,
447 : true, "TIN_IN"),
448 : std::make_tuple("TIN(((1 2,1 3,10 3,1 2)))", 0.9, 1.9, 0.95, 2.1,
449 : false, "TIN_OUT"),
450 : std::make_tuple("TIN EMPTY", 0.9, 1.9, 1.1, 2.1, false,
451 : "TIN_EMPTY"),
452 : std::make_tuple("TIN Z (((1 2 -10,1 3 -10,10 3 -10,1 2 -10)))", 0.9,
453 : 1.9, 1.1, 2.1, true, "TINZ_IN"),
454 : std::make_tuple("TIN Z (((1 2 -10,1 3 -10,10 3 -10,1 2 -10)))", 0.9,
455 : 1.9, 0.95, 2.1, false, "TINZ_OUT"),
456 1 : };
457 : }
458 : };
459 :
460 151 : TEST_P(OGRWKBIntersectsPessimisticFixture, test)
461 : {
462 75 : const char *pszInput = std::get<0>(GetParam());
463 75 : const double dfMinX = std::get<1>(GetParam());
464 75 : const double dfMinY = std::get<2>(GetParam());
465 75 : const double dfMaxX = std::get<3>(GetParam());
466 75 : const double dfMaxY = std::get<4>(GetParam());
467 75 : const bool bIntersects = std::get<5>(GetParam());
468 :
469 75 : OGRGeometry *poGeom = nullptr;
470 75 : EXPECT_EQ(OGRGeometryFactory::createFromWkt(pszInput, nullptr, &poGeom),
471 : OGRERR_NONE);
472 75 : ASSERT_TRUE(poGeom != nullptr);
473 150 : std::vector<GByte> abyWkb(poGeom->WkbSize());
474 75 : poGeom->exportToWkb(wkbNDR, abyWkb.data(), wkbVariantIso);
475 75 : delete poGeom;
476 75 : OGREnvelope sEnvelope;
477 75 : sEnvelope.MinX = dfMinX;
478 75 : sEnvelope.MinY = dfMinY;
479 75 : sEnvelope.MaxX = dfMaxX;
480 75 : sEnvelope.MaxY = dfMaxY;
481 75 : EXPECT_EQ(
482 : OGRWKBIntersectsPessimistic(abyWkb.data(), abyWkb.size(), sEnvelope),
483 : bIntersects);
484 :
485 75 : if (abyWkb.size() > 9)
486 : {
487 62 : EXPECT_EQ(OGRWKBIntersectsPessimistic(abyWkb.data(), 9, sEnvelope),
488 : false);
489 :
490 62 : if (!STARTS_WITH(pszInput, "POINT"))
491 : {
492 : // Corrupt number of sub-geometries
493 54 : abyWkb[5] = 0xff;
494 54 : abyWkb[6] = 0xff;
495 54 : abyWkb[7] = 0xff;
496 54 : abyWkb[8] = 0xff;
497 54 : EXPECT_EQ(OGRWKBIntersectsPessimistic(abyWkb.data(), abyWkb.size(),
498 : sEnvelope),
499 : false);
500 : }
501 : }
502 : }
503 :
504 152 : INSTANTIATE_TEST_SUITE_P(
505 : test_ogr_wkb, OGRWKBIntersectsPessimisticFixture,
506 : ::testing::ValuesIn(OGRWKBIntersectsPessimisticFixture::GetTupleValues()),
507 : [](const ::testing::TestParamInfo<
508 : OGRWKBIntersectsPessimisticFixture::ParamType> &l_info)
509 : { return std::get<6>(l_info.param); });
510 :
511 : class OGRWKBTransformFixture
512 : : public test_ogr_wkb,
513 : public ::testing::WithParamInterface<
514 : std::tuple<const char *, OGRwkbByteOrder, const char *, const char *>>
515 : {
516 : public:
517 : static std::vector<
518 : std::tuple<const char *, OGRwkbByteOrder, const char *, const char *>>
519 1 : GetTupleValues()
520 : {
521 : return {
522 : std::make_tuple("POINT EMPTY", wkbNDR, "POINT EMPTY",
523 : "POINT_EMPTY_NDR"),
524 : std::make_tuple("POINT EMPTY", wkbXDR, "POINT EMPTY",
525 : "POINT_EMPTY_XDR"),
526 : std::make_tuple("POINT (1 2)", wkbNDR, "POINT (2 4)", "POINT_NDR"),
527 : std::make_tuple("POINT (1 2)", wkbXDR, "POINT (2 4)", "POINT_XDR"),
528 : std::make_tuple("POINT Z EMPTY", wkbNDR, "POINT Z EMPTY",
529 : "POINT_Z_EMPTY_NDR"),
530 : std::make_tuple("POINT Z EMPTY", wkbXDR, "POINT Z EMPTY",
531 : "POINT_Z_EMPTY_XDR"),
532 : std::make_tuple("POINT Z (1 2 3)", wkbNDR, "POINT Z (2 4 6)",
533 : "POINT_Z_NDR"),
534 : std::make_tuple("POINT Z (1 2 3)", wkbXDR, "POINT Z (2 4 6)",
535 : "POINT_Z_XDR"),
536 : std::make_tuple("POINT M EMPTY", wkbNDR, "POINT M EMPTY",
537 : "POINT_M_EMPTY_NDR"),
538 : std::make_tuple("POINT M EMPTY", wkbXDR, "POINT M EMPTY",
539 : "POINT_M_EMPTY_XDR"),
540 : std::make_tuple("POINT M (1 2 -10)", wkbNDR, "POINT M (2 4 -10)",
541 : "POINT_M_NDR"),
542 : std::make_tuple("POINT M (1 2 -10)", wkbXDR, "POINT M (2 4 -10)",
543 : "POINT_M_XDR"),
544 : std::make_tuple("POINT ZM EMPTY", wkbNDR, "POINT ZM EMPTY",
545 : "POINT_ZM_EMPTY_NDR"),
546 : std::make_tuple("POINT ZM EMPTY", wkbXDR, "POINT ZM EMPTY",
547 : "POINT_ZM_EMPTY_XDR"),
548 : std::make_tuple("POINT ZM (1 2 3 10)", wkbNDR,
549 : "POINT ZM (2 4 6 10)", "POINT_ZM_NDR"),
550 : std::make_tuple("POINT ZM (1 2 3 10)", wkbXDR,
551 : "POINT ZM (2 4 6 10)", "POINT_ZM_XDR"),
552 :
553 : std::make_tuple("LINESTRING EMPTY", wkbNDR, "LINESTRING EMPTY",
554 : "LINESTRING_EMPTY"),
555 : std::make_tuple("LINESTRING (1 2,11 12)", wkbNDR,
556 : "LINESTRING (2 4,12 14)", "LINESTRING_NDR"),
557 : std::make_tuple("LINESTRING (1 2,11 12)", wkbXDR,
558 : "LINESTRING (2 4,12 14)", "LINESTRING_XDR"),
559 : std::make_tuple("LINESTRING Z EMPTY", wkbNDR, "LINESTRING Z EMPTY",
560 : "LINESTRING_Z_EMPTY"),
561 : std::make_tuple("LINESTRING Z (1 2 3,11 12 13)", wkbNDR,
562 : "LINESTRING Z (2 4 6,12 14 16)",
563 : "LINESTRING_Z_NDR"),
564 : std::make_tuple("LINESTRING Z (1 2 3,11 12 13)", wkbXDR,
565 : "LINESTRING Z (2 4 6,12 14 16)",
566 : "LINESTRING_Z_XDR"),
567 : std::make_tuple("LINESTRING M EMPTY", wkbNDR, "LINESTRING M EMPTY",
568 : "LINESTRING_M_EMPTY"),
569 : std::make_tuple("LINESTRING M (1 2 -10,11 12 -20)", wkbNDR,
570 : "LINESTRING M (2 4 -10,12 14 -20)",
571 : "LINESTRING_M_NDR"),
572 : std::make_tuple("LINESTRING M (1 2 -10,11 12 -20)", wkbXDR,
573 : "LINESTRING M (2 4 -10,12 14 -20)",
574 : "LINESTRING_M_XDR"),
575 : std::make_tuple("LINESTRING ZM EMPTY", wkbNDR,
576 : "LINESTRING ZM EMPTY", "LINESTRING_ZM_EMPTY"),
577 : std::make_tuple("LINESTRING ZM (1 2 3 -10,11 12 13 -20)", wkbNDR,
578 : "LINESTRING ZM (2 4 6 -10,12 14 16 -20)",
579 : "LINESTRING_ZM_NDR"),
580 : std::make_tuple("LINESTRING ZM (1 2 3 -10,11 12 13 -20)", wkbXDR,
581 : "LINESTRING ZM (2 4 6 -10,12 14 16 -20)",
582 : "LINESTRING_ZM_XDR"),
583 :
584 : // I know the polygon is invalid, but this is enough for our purposes
585 : std::make_tuple("POLYGON EMPTY", wkbNDR, "POLYGON EMPTY",
586 : "POLYGON_EMPTY"),
587 : std::make_tuple("POLYGON ((1 2,11 12))", wkbNDR,
588 : "POLYGON ((2 4,12 14))", "POLYGON_NDR"),
589 : std::make_tuple("POLYGON ((1 2,11 12))", wkbXDR,
590 : "POLYGON ((2 4,12 14))", "POLYGON_XDR"),
591 : std::make_tuple("POLYGON ((1 2,11 12),(21 22,31 32))", wkbNDR,
592 : "POLYGON ((2 4,12 14),(22 24,32 34))",
593 : "POLYGON_TWO_RINGS"),
594 : std::make_tuple("POLYGON Z EMPTY", wkbNDR, "POLYGON Z EMPTY",
595 : "POLYGON_Z_EMPTY"),
596 : std::make_tuple("POLYGON Z ((1 2 3,11 12 13))", wkbNDR,
597 : "POLYGON Z ((2 4 6,12 14 16))", "POLYGON_Z_NDR"),
598 : std::make_tuple("POLYGON Z ((1 2 3,11 12 13))", wkbXDR,
599 : "POLYGON Z ((2 4 6,12 14 16))", "POLYGON_Z_XDR"),
600 : std::make_tuple("POLYGON M EMPTY", wkbNDR, "POLYGON M EMPTY",
601 : "POLYGON_M_EMPTY"),
602 : std::make_tuple("POLYGON M ((1 2 -10,11 12 -20))", wkbNDR,
603 : "POLYGON M ((2 4 -10,12 14 -20))", "POLYGON_M_NDR"),
604 : std::make_tuple("POLYGON M ((1 2 -10,11 12 -20))", wkbXDR,
605 : "POLYGON M ((2 4 -10,12 14 -20))", "POLYGON_M_XDR"),
606 : std::make_tuple("POLYGON ZM EMPTY", wkbNDR, "POLYGON ZM EMPTY",
607 : "POLYGON_ZM_EMPTY"),
608 : std::make_tuple("POLYGON ZM ((1 2 3 -10,11 12 13 -20))", wkbNDR,
609 : "POLYGON ZM ((2 4 6 -10,12 14 16 -20))",
610 : "POLYGON_ZM_NDR"),
611 : std::make_tuple("POLYGON ZM ((1 2 3 -10,11 12 13 -20))", wkbXDR,
612 : "POLYGON ZM ((2 4 6 -10,12 14 16 -20))",
613 : "POLYGON_ZM_XDR"),
614 :
615 : std::make_tuple("MULTIPOINT EMPTY", wkbNDR, "MULTIPOINT EMPTY",
616 : "MULTIPOINT_EMPTY_NDR"),
617 : std::make_tuple("MULTIPOINT ((1 2),(11 12))", wkbNDR,
618 : "MULTIPOINT ((2 4),(12 14))", "MULTIPOINT_NDR"),
619 : std::make_tuple("MULTIPOINT Z ((1 2 3),(11 12 13))", wkbXDR,
620 : "MULTIPOINT Z ((2 4 6),(12 14 16))",
621 : "MULTIPOINT_Z_XDR"),
622 :
623 : std::make_tuple("MULTILINESTRING ((1 2,11 12))", wkbNDR,
624 : "MULTILINESTRING ((2 4,12 14))",
625 : "MULTILINESTRING_NDR"),
626 :
627 : std::make_tuple("MULTIPOLYGON (((1 2,11 12)))", wkbNDR,
628 : "MULTIPOLYGON (((2 4,12 14)))", "MULTIPOLYGON_NDR"),
629 :
630 : std::make_tuple("GEOMETRYCOLLECTION (POLYGON ((1 2,11 12)))",
631 : wkbNDR,
632 : "GEOMETRYCOLLECTION (POLYGON ((2 4,12 14)))",
633 : "GEOMETRYCOLLECTION_NDR"),
634 :
635 : std::make_tuple("CIRCULARSTRING (1 2,11 12,21 22)", wkbNDR,
636 : "CIRCULARSTRING (2 4,12 14,22 24)",
637 : "CIRCULARSTRING_NDR"),
638 :
639 : std::make_tuple("COMPOUNDCURVE ((1 2,11 12))", wkbNDR,
640 : "COMPOUNDCURVE ((2 4,12 14))", "COMPOUNDCURVE_NDR"),
641 :
642 : std::make_tuple("CURVEPOLYGON ((1 2,11 12,21 22,1 2))", wkbNDR,
643 : "CURVEPOLYGON ((2 4,12 14,22 24,2 4))",
644 : "CURVEPOLYGON_NDR"),
645 :
646 : std::make_tuple("MULTICURVE ((1 2,11 12))", wkbNDR,
647 : "MULTICURVE ((2 4,12 14))", "MULTICURVE_NDR"),
648 :
649 : std::make_tuple("MULTISURFACE (((1 2,11 12)))", wkbNDR,
650 : "MULTISURFACE (((2 4,12 14)))", "MULTISURFACE_NDR"),
651 :
652 : std::make_tuple("TRIANGLE ((1 2,11 12,21 22,1 2))", wkbNDR,
653 : "TRIANGLE ((2 4,12 14,22 24,2 4))", "TRIANGLE_NDR"),
654 :
655 : std::make_tuple("POLYHEDRALSURFACE (((1 2,11 12,21 22,1 2)))",
656 : wkbNDR,
657 : "POLYHEDRALSURFACE (((2 4,12 14,22 24,2 4)))",
658 : "POLYHEDRALSURFACE_NDR"),
659 :
660 : std::make_tuple("TIN (((1 2,11 12,21 22,1 2)))", wkbNDR,
661 : "TIN (((2 4,12 14,22 24,2 4)))", "TIN_NDR"),
662 1 : };
663 : }
664 : };
665 :
666 : struct MyCT final : public OGRCoordinateTransformation
667 : {
668 : const bool m_bSuccess;
669 :
670 112 : explicit MyCT(bool bSuccess = true) : m_bSuccess(bSuccess)
671 : {
672 112 : }
673 :
674 55 : const OGRSpatialReference *GetSourceCS() const override
675 : {
676 55 : return nullptr;
677 : }
678 :
679 55 : const OGRSpatialReference *GetTargetCS() const override
680 : {
681 55 : return nullptr;
682 : }
683 :
684 3976 : int Transform(size_t nCount, double *x, double *y, double *z, double *,
685 : int *pabSuccess) override
686 : {
687 7952 : for (size_t i = 0; i < nCount; ++i)
688 : {
689 3976 : x[i] += 1;
690 3976 : y[i] += 2;
691 3976 : if (z)
692 3976 : z[i] += 3;
693 3976 : if (pabSuccess)
694 3976 : pabSuccess[i] = m_bSuccess;
695 : }
696 3976 : return true;
697 : }
698 :
699 55 : OGRCoordinateTransformation *Clone() const override
700 : {
701 55 : return new MyCT();
702 : }
703 :
704 55 : OGRCoordinateTransformation *GetInverse() const override
705 : {
706 55 : return nullptr;
707 : } // unused
708 : };
709 :
710 111 : TEST_P(OGRWKBTransformFixture, test)
711 : {
712 55 : const char *pszInput = std::get<0>(GetParam());
713 55 : OGRwkbByteOrder eByteOrder = std::get<1>(GetParam());
714 55 : const char *pszOutput = std::get<2>(GetParam());
715 :
716 55 : MyCT oCT;
717 55 : oCT.GetSourceCS(); // just for code coverage purpose
718 55 : oCT.GetTargetCS(); // just for code coverage purpose
719 55 : delete oCT.Clone(); // just for code coverage purpose
720 55 : delete oCT.GetInverse(); // just for code coverage purpose
721 :
722 55 : OGRGeometry *poGeom = nullptr;
723 55 : EXPECT_EQ(OGRGeometryFactory::createFromWkt(pszInput, nullptr, &poGeom),
724 : OGRERR_NONE);
725 55 : ASSERT_TRUE(poGeom != nullptr);
726 55 : std::vector<GByte> abyWkb(poGeom->WkbSize());
727 55 : poGeom->exportToWkb(eByteOrder, abyWkb.data(), wkbVariantIso);
728 55 : delete poGeom;
729 :
730 : OGRWKBTransformCache oCache;
731 55 : OGREnvelope3D sEnv;
732 55 : EXPECT_TRUE(
733 : OGRWKBTransform(abyWkb.data(), abyWkb.size(), &oCT, oCache, sEnv));
734 55 : const auto abyWkbOri = abyWkb;
735 :
736 55 : poGeom = nullptr;
737 55 : OGRGeometryFactory::createFromWkb(abyWkb.data(), nullptr, &poGeom,
738 : abyWkb.size());
739 55 : ASSERT_TRUE(poGeom != nullptr);
740 55 : char *pszWKT = nullptr;
741 55 : poGeom->exportToWkt(&pszWKT, wkbVariantIso);
742 55 : delete poGeom;
743 55 : EXPECT_STREQ(pszWKT, pszOutput);
744 55 : CPLFree(pszWKT);
745 :
746 : {
747 110 : CPLErrorHandlerPusher oErrorHandler(CPLQuietErrorHandler);
748 :
749 : // Truncated geometry
750 2443 : for (size_t i = 0; i < abyWkb.size(); ++i)
751 : {
752 2388 : abyWkb = abyWkbOri;
753 2388 : EXPECT_FALSE(OGRWKBTransform(abyWkb.data(), i, &oCT, oCache, sEnv));
754 : }
755 :
756 : // Check altering all bytes
757 2443 : for (size_t i = 0; i < abyWkb.size(); ++i)
758 : {
759 2388 : abyWkb = abyWkbOri;
760 2388 : abyWkb[i] = 0xff;
761 2388 : CPL_IGNORE_RET_VAL(OGRWKBTransform(abyWkb.data(), abyWkb.size(),
762 : &oCT, oCache, sEnv));
763 : }
764 :
765 55 : if (abyWkb.size() > 9)
766 : {
767 46 : abyWkb = abyWkbOri;
768 46 : if (!STARTS_WITH(pszInput, "POINT"))
769 : {
770 : // Corrupt number of sub-geometries
771 30 : abyWkb[5] = 0xff;
772 30 : abyWkb[6] = 0xff;
773 30 : abyWkb[7] = 0xff;
774 30 : abyWkb[8] = 0xff;
775 30 : EXPECT_FALSE(OGRWKBTransform(abyWkb.data(), abyWkb.size(), &oCT,
776 : oCache, sEnv));
777 : }
778 : }
779 : }
780 : }
781 :
782 112 : INSTANTIATE_TEST_SUITE_P(
783 : test_ogr_wkb, OGRWKBTransformFixture,
784 : ::testing::ValuesIn(OGRWKBTransformFixture::GetTupleValues()),
785 : [](const ::testing::TestParamInfo<OGRWKBTransformFixture::ParamType>
786 : &l_info) { return std::get<3>(l_info.param); });
787 :
788 4 : TEST_F(test_ogr_wkb, OGRWKBTransformFixture_rec_collection)
789 : {
790 2 : std::vector<GByte> abyWkb;
791 1 : constexpr int BEYOND_ALLOWED_RECURSION_LEVEL = 128;
792 129 : for (int i = 0; i < BEYOND_ALLOWED_RECURSION_LEVEL; ++i)
793 : {
794 128 : abyWkb.push_back(wkbNDR);
795 128 : abyWkb.push_back(wkbGeometryCollection);
796 128 : abyWkb.push_back(0);
797 128 : abyWkb.push_back(0);
798 128 : abyWkb.push_back(0);
799 128 : abyWkb.push_back(1);
800 128 : abyWkb.push_back(0);
801 128 : abyWkb.push_back(0);
802 128 : abyWkb.push_back(0);
803 : }
804 : {
805 1 : abyWkb.push_back(wkbNDR);
806 1 : abyWkb.push_back(wkbGeometryCollection);
807 1 : abyWkb.push_back(0);
808 1 : abyWkb.push_back(0);
809 1 : abyWkb.push_back(0);
810 1 : abyWkb.push_back(0);
811 1 : abyWkb.push_back(0);
812 1 : abyWkb.push_back(0);
813 1 : abyWkb.push_back(0);
814 : }
815 :
816 2 : MyCT oCT;
817 : OGRWKBTransformCache oCache;
818 1 : OGREnvelope3D sEnv;
819 1 : EXPECT_FALSE(
820 : OGRWKBTransform(abyWkb.data(), abyWkb.size(), &oCT, oCache, sEnv));
821 1 : }
822 :
823 4 : TEST_F(test_ogr_wkb, OGRWKBTransformFixture_ct_failure)
824 : {
825 2 : MyCT oCT(/* bSuccess = */ false);
826 : OGRWKBTransformCache oCache;
827 1 : OGREnvelope3D sEnv;
828 : {
829 2 : OGRPoint p(1, 2);
830 2 : std::vector<GByte> abyWkb(p.WkbSize());
831 1 : static_cast<OGRGeometry &>(p).exportToWkb(wkbNDR, abyWkb.data(),
832 : wkbVariantIso);
833 :
834 1 : EXPECT_FALSE(
835 : OGRWKBTransform(abyWkb.data(), abyWkb.size(), &oCT, oCache, sEnv));
836 : }
837 : {
838 2 : OGRLineString ls;
839 1 : ls.addPoint(1, 2);
840 2 : std::vector<GByte> abyWkb(ls.WkbSize());
841 1 : static_cast<OGRGeometry &>(ls).exportToWkb(wkbNDR, abyWkb.data(),
842 : wkbVariantIso);
843 :
844 1 : EXPECT_FALSE(
845 : OGRWKBTransform(abyWkb.data(), abyWkb.size(), &oCT, oCache, sEnv));
846 : }
847 : {
848 2 : OGRPolygon p;
849 2 : auto poLR = std::make_unique<OGRLinearRing>();
850 1 : poLR->addPoint(1, 2);
851 1 : p.addRing(std::move(poLR));
852 2 : std::vector<GByte> abyWkb(p.WkbSize());
853 1 : static_cast<OGRGeometry &>(p).exportToWkb(wkbNDR, abyWkb.data(),
854 : wkbVariantIso);
855 :
856 1 : EXPECT_FALSE(
857 : OGRWKBTransform(abyWkb.data(), abyWkb.size(), &oCT, oCache, sEnv));
858 : }
859 1 : }
860 :
861 : } // namespace
|