LCOV - code coverage report
Current view: top level - autotest/cpp - test_ogr_wkb.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 97 97 100.0 %
Date: 2024-05-14 13:00:50 Functions: 28 28 100.0 %

          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             :  * 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             : #include "gdal_unit_test.h"
      30             : 
      31             : #include "ogr_geometry.h"
      32             : #include "ogr_wkb.h"
      33             : 
      34             : #include "gtest_include.h"
      35             : 
      36             : #include <limits>
      37             : 
      38             : namespace
      39             : {
      40             : 
      41             : struct test_ogr_wkb : public ::testing::Test
      42             : {
      43             : };
      44             : 
      45             : class OGRWKBGetEnvelopeFixture
      46             :     : public test_ogr_wkb,
      47             :       public ::testing::WithParamInterface<std::tuple<
      48             :           const char *, double, double, double, double, const char *>>
      49             : {
      50             :     static constexpr double INF = std::numeric_limits<double>::infinity();
      51             : 
      52             :   public:
      53             :     static std::vector<
      54             :         std::tuple<const char *, double, double, double, double, const char *>>
      55           1 :     GetTupleValues()
      56             :     {
      57             :         return {
      58             :             std::make_tuple("POINT(1 2)", 1, 2, 1, 2, "POINT"),
      59             :             std::make_tuple("POINT EMPTY", INF, INF, -INF, -INF, "POINT_EMPTY"),
      60             :             std::make_tuple("POINT Z (1 2 3)", 1, 2, 1, 2, "POINT_3D"),
      61             :             std::make_tuple("LINESTRING(3 4,1 2)", 1, 2, 3, 4, "LINESTRING"),
      62             :             std::make_tuple("LINESTRING EMPTY", INF, INF, -INF, -INF,
      63             :                             "LINESTRING_EMPTY"),
      64             :             std::make_tuple("LINESTRING Z (3 4 5,1 2 6)", 1, 2, 3, 4,
      65             :                             "LINESTRING_3D"),
      66             :             std::make_tuple("POLYGON((0 1,0 2,3 2,0 1))", 0, 1, 3, 2,
      67             :                             "POLYGON"),
      68             :             std::make_tuple("POLYGON EMPTY", INF, INF, -INF, -INF,
      69             :                             "POLYGON_EMPTY"),
      70             :             std::make_tuple("POLYGON Z ((0 1 10,0 2 20,3 2 20,0 1 10))", 0, 1,
      71             :                             3, 2, "POLYGON_3D"),
      72             :             std::make_tuple("MULTIPOINT((1 2),(3 4))", 1, 2, 3, 4,
      73             :                             "MULTIPOINT"),
      74             :             std::make_tuple("MULTIPOINT EMPTY", INF, INF, -INF, -INF,
      75             :                             "MULTIPOINT_EMPTY"),
      76             :             std::make_tuple("MULTIPOINT Z ((1 2 10),(3 4 20))", 1, 2, 3, 4,
      77             :                             "MULTIPOINT_3D"),
      78             :             std::make_tuple("MULTILINESTRING((3 4,1 2),(5 6,7 8))", 1, 2, 7, 8,
      79             :                             "MULTILINESTRING"),
      80             :             std::make_tuple("MULTILINESTRING EMPTY", INF, INF, -INF, -INF,
      81             :                             "MULTILINESTRING_EMPTY"),
      82             :             std::make_tuple(
      83             :                 "MULTILINESTRING Z ((3 4 10,1 2 20),(5 6 10,7 8 20))", 1, 2, 7,
      84             :                 8, "MULTILINESTRING_3D"),
      85             :             std::make_tuple(
      86             :                 "MULTIPOLYGON(((0 1,0 2,3 2,0 1)),((0 -1,0 -2,-3 -2,0 -1)))",
      87             :                 -3, -2, 3, 2, "MULTIPOLYGON"),
      88             :             std::make_tuple("MULTIPOLYGON EMPTY", INF, INF, -INF, -INF,
      89             :                             "MULTIPOLYGON_EMPTY"),
      90             :             std::make_tuple("MULTIPOLYGON Z (((0 1 10,0 2 20,3 2 20,0 1 "
      91             :                             "10)),((0 -1 -10,0 -2 -20,-3 -2 -20,0 -1 -10)))",
      92             :                             -3, -2, 3, 2, "MULTIPOLYGON_3D"),
      93             :             std::make_tuple("GEOMETRYCOLLECTION(POINT(1 2),POINT(3 4))", 1, 2,
      94             :                             3, 4, "GEOMETRYCOLLECTION"),
      95             :             std::make_tuple("CIRCULARSTRING(0 10,1 11,2 10)", 0, 10, 2, 11,
      96             :                             "CIRCULARSTRING"),
      97             :             std::make_tuple("COMPOUNDCURVE((3 4,1 2))", 1, 2, 3, 4,
      98             :                             "COMPOUNDCURVE"),
      99             :             std::make_tuple("CURVEPOLYGON((0 1,0 2,3 2,0 1))", 0, 1, 3, 2,
     100             :                             "CURVEPOLYGON"),
     101             :             std::make_tuple("MULTICURVE((3 4,1 2),(5 6,7 8))", 1, 2, 7, 8,
     102             :                             "MULTICURVE"),
     103             :             std::make_tuple(
     104             :                 "MULTISURFACE(((0 1,0 2,3 2,0 1)),((0 -1,0 -2,-3 -2,0 -1)))",
     105             :                 -3, -2, 3, 2, "MULTISURFACE"),
     106             :             std::make_tuple("TRIANGLE((0 1,0 2,3 2,0 1))", 0, 1, 3, 2,
     107             :                             "TRIANGLE"),
     108             :             std::make_tuple("POLYHEDRALSURFACE(((0 1,0 2,3 2,0 1)))", 0, 1, 3,
     109             :                             2, "POLYHEDRALSURFACE"),
     110             :             std::make_tuple("TIN(((0 1,0 2,3 2,0 1)))", 0, 1, 3, 2, "TIN"),
     111           1 :         };
     112             :     }
     113             : };
     114             : 
     115          55 : TEST_P(OGRWKBGetEnvelopeFixture, test)
     116             : {
     117          27 :     const char *pszInput = std::get<0>(GetParam());
     118          27 :     const double dfExpectedMinX = std::get<1>(GetParam());
     119          27 :     const double dfExpectedMinY = std::get<2>(GetParam());
     120          27 :     const double dfExpectedMaxX = std::get<3>(GetParam());
     121          27 :     const double dfExpectedMaxY = std::get<4>(GetParam());
     122             : 
     123          27 :     OGRGeometry *poGeom = nullptr;
     124          27 :     ASSERT_EQ(OGRGeometryFactory::createFromWkt(pszInput, nullptr, &poGeom),
     125             :               OGRERR_NONE);
     126          27 :     ASSERT_TRUE(poGeom != nullptr);
     127          54 :     std::vector<GByte> abyWkb(poGeom->WkbSize());
     128          27 :     poGeom->exportToWkb(wkbNDR, abyWkb.data(), wkbVariantIso);
     129          27 :     delete poGeom;
     130          27 :     OGREnvelope sEnvelope;
     131          27 :     EXPECT_EQ(OGRWKBGetBoundingBox(abyWkb.data(), abyWkb.size(), sEnvelope),
     132             :               true);
     133          27 :     EXPECT_EQ(sEnvelope.MinX, dfExpectedMinX);
     134          27 :     EXPECT_EQ(sEnvelope.MinY, dfExpectedMinY);
     135          27 :     EXPECT_EQ(sEnvelope.MaxX, dfExpectedMaxX);
     136          27 :     EXPECT_EQ(sEnvelope.MaxY, dfExpectedMaxY);
     137             : }
     138             : 
     139          56 : INSTANTIATE_TEST_SUITE_P(
     140             :     test_ogr_wkb, OGRWKBGetEnvelopeFixture,
     141             :     ::testing::ValuesIn(OGRWKBGetEnvelopeFixture::GetTupleValues()),
     142             :     [](const ::testing::TestParamInfo<OGRWKBGetEnvelopeFixture::ParamType>
     143             :            &l_info) { return std::get<5>(l_info.param); });
     144             : 
     145             : class OGRWKBGetEnvelope3DFixture
     146             :     : public test_ogr_wkb,
     147             :       public ::testing::WithParamInterface<
     148             :           std::tuple<const char *, double, double, double, double, double,
     149             :                      double, const char *>>
     150             : {
     151             :     static constexpr double INF = std::numeric_limits<double>::infinity();
     152             : 
     153             :   public:
     154             :     static std::vector<std::tuple<const char *, double, double, double, double,
     155             :                                   double, double, const char *>>
     156           1 :     GetTupleValues()
     157             :     {
     158             :         return {
     159             :             std::make_tuple("POINT(1 2)", 1, 2, INF, 1, 2, -INF, "POINT"),
     160             :             std::make_tuple("POINT EMPTY", INF, INF, INF, -INF, -INF, -INF,
     161             :                             "POINT_EMPTY"),
     162             :             std::make_tuple("POINT Z (1 2 3)", 1, 2, 3, 1, 2, 3, "POINT_3D"),
     163             :             std::make_tuple("LINESTRING(3 4,1 2)", 1, 2, INF, 3, 4, -INF,
     164             :                             "LINESTRING"),
     165             :             std::make_tuple("LINESTRING EMPTY", INF, INF, INF, -INF, -INF, -INF,
     166             :                             "LINESTRING_EMPTY"),
     167             :             std::make_tuple("LINESTRING Z (3 4 5,1 2 6)", 1, 2, 5, 3, 4, 6,
     168             :                             "LINESTRING_3D"),
     169             :             std::make_tuple("POLYGON((0 1,0 2,3 2,0 1))", 0, 1, INF, 3, 2, -INF,
     170             :                             "POLYGON"),
     171             :             std::make_tuple("POLYGON EMPTY", INF, INF, INF, -INF, -INF, -INF,
     172             :                             "POLYGON_EMPTY"),
     173             :             std::make_tuple("POLYGON Z ((0 1 10,0 2 20,3 2 20,0 1 10))", 0, 1,
     174             :                             10, 3, 2, 20, "POLYGON_3D"),
     175             :             std::make_tuple("MULTIPOINT((1 2),(3 4))", 1, 2, INF, 3, 4, -INF,
     176             :                             "MULTIPOINT"),
     177             :             std::make_tuple("MULTIPOINT EMPTY", INF, INF, INF, -INF, -INF, -INF,
     178             :                             "MULTIPOINT_EMPTY"),
     179             :             std::make_tuple("MULTIPOINT Z ((1 2 10),(3 4 20))", 1, 2, 10, 3, 4,
     180             :                             20, "MULTIPOINT_3D"),
     181             :             std::make_tuple("MULTILINESTRING((3 4,1 2),(5 6,7 8))", 1, 2, INF,
     182             :                             7, 8, -INF, "MULTILINESTRING"),
     183             :             std::make_tuple("MULTILINESTRING EMPTY", INF, INF, INF, -INF, -INF,
     184             :                             -INF, "MULTILINESTRING_EMPTY"),
     185             :             std::make_tuple(
     186             :                 "MULTILINESTRING Z ((3 4 10,1 2 20),(5 6 10,7 8 20))", 1, 2, 10,
     187             :                 7, 8, 20, "MULTILINESTRING_3D"),
     188             :             std::make_tuple(
     189             :                 "MULTIPOLYGON(((0 1,0 2,3 2,0 1)),((0 -1,0 -2,-3 -2,0 -1)))",
     190             :                 -3, -2, INF, 3, 2, -INF, "MULTIPOLYGON"),
     191             :             std::make_tuple("MULTIPOLYGON EMPTY", INF, INF, INF, -INF, -INF,
     192             :                             -INF, "MULTIPOLYGON_EMPTY"),
     193             :             std::make_tuple("MULTIPOLYGON Z (((0 1 10,0 2 20,3 2 20,0 1 "
     194             :                             "10)),((0 -1 -10,0 -2 -20,-3 -2 -20,0 -1 -10)))",
     195             :                             -3, -2, -20, 3, 2, 20, "MULTIPOLYGON_3D"),
     196           1 :         };
     197             :     }
     198             : };
     199             : 
     200          37 : TEST_P(OGRWKBGetEnvelope3DFixture, test)
     201             : {
     202          18 :     const char *pszInput = std::get<0>(GetParam());
     203          18 :     const double dfExpectedMinX = std::get<1>(GetParam());
     204          18 :     const double dfExpectedMinY = std::get<2>(GetParam());
     205          18 :     const double dfExpectedMinZ = std::get<3>(GetParam());
     206          18 :     const double dfExpectedMaxX = std::get<4>(GetParam());
     207          18 :     const double dfExpectedMaxY = std::get<5>(GetParam());
     208          18 :     const double dfExpectedMaxZ = std::get<6>(GetParam());
     209             : 
     210          18 :     OGRGeometry *poGeom = nullptr;
     211          18 :     ASSERT_EQ(OGRGeometryFactory::createFromWkt(pszInput, nullptr, &poGeom),
     212             :               OGRERR_NONE);
     213          18 :     ASSERT_TRUE(poGeom != nullptr);
     214          36 :     std::vector<GByte> abyWkb(poGeom->WkbSize());
     215          18 :     poGeom->exportToWkb(wkbNDR, abyWkb.data(), wkbVariantIso);
     216          18 :     delete poGeom;
     217          18 :     OGREnvelope3D sEnvelope;
     218          18 :     EXPECT_EQ(OGRWKBGetBoundingBox(abyWkb.data(), abyWkb.size(), sEnvelope),
     219             :               true);
     220          18 :     EXPECT_EQ(sEnvelope.MinX, dfExpectedMinX);
     221          18 :     EXPECT_EQ(sEnvelope.MinY, dfExpectedMinY);
     222          18 :     EXPECT_EQ(sEnvelope.MinZ, dfExpectedMinZ);
     223          18 :     EXPECT_EQ(sEnvelope.MaxX, dfExpectedMaxX);
     224          18 :     EXPECT_EQ(sEnvelope.MaxY, dfExpectedMaxY);
     225          18 :     EXPECT_EQ(sEnvelope.MaxZ, dfExpectedMaxZ);
     226             : }
     227             : 
     228          38 : INSTANTIATE_TEST_SUITE_P(
     229             :     test_ogr_wkb, OGRWKBGetEnvelope3DFixture,
     230             :     ::testing::ValuesIn(OGRWKBGetEnvelope3DFixture::GetTupleValues()),
     231             :     [](const ::testing::TestParamInfo<OGRWKBGetEnvelope3DFixture::ParamType>
     232             :            &l_info) { return std::get<7>(l_info.param); });
     233             : 
     234             : class OGRWKBFixupCounterClockWiseExternalRingFixture
     235             :     : public test_ogr_wkb,
     236             :       public ::testing::WithParamInterface<
     237             :           std::tuple<const char *, const char *, const char *>>
     238             : {
     239             :   public:
     240             :     static std::vector<std::tuple<const char *, const char *, const char *>>
     241           1 :     GetTupleValues()
     242             :     {
     243             :         return {
     244             :             std::make_tuple("MULTIPOLYGON (((0 1,0 0,1 1,0 1),(0.2 0.3,0.2 "
     245             :                             "0.8,0.7 0.8,0.2 0.3)))",
     246             :                             "MULTIPOLYGON (((0 1,0 0,1 1,0 1),(0.2 0.3,0.2 "
     247             :                             "0.8,0.7 0.8,0.2 0.3)))",
     248             :                             "MULTIPOLYGON_CCW"),
     249             :             std::make_tuple("MULTIPOLYGON (((1 1,0 0,0 1,1 1),(0.2 0.3,0.7 "
     250             :                             "0.8,0.2 0.8,0.2 0.3)))",
     251             :                             "MULTIPOLYGON (((1 1,0 1,0 0,1 1),(0.2 0.3,0.2 "
     252             :                             "0.8,0.7 0.8,0.2 0.3)))",
     253             :                             "MULTIPOLYGON_CW"),
     254             :             std::make_tuple(
     255             :                 "MULTIPOLYGON Z (((0 0 10,0 1 10,1 1 10,0 0 10),(0.2 0.3 "
     256             :                 "10,0.7 0.8 10,0.2 0.8 10,0.2 0.3 10)))",
     257             :                 "MULTIPOLYGON Z (((0 0 10,1 1 10,0 1 10,0 0 10),(0.2 0.3 "
     258             :                 "10,0.2 0.8 10,0.7 0.8 10,0.2 0.3 10)))",
     259             :                 "MULTIPOLYGON_CW_3D"),
     260             :             std::make_tuple("MULTIPOLYGON (((0 0,0 0,1 1,1 1,0 1,0 1,0 0)))",
     261             :                             "MULTIPOLYGON (((0 0,0 0,1 1,1 1,0 1,0 1,0 0)))",
     262             :                             "MULTIPOLYGON_CCW_REPEATED_POINTS"),
     263             :             std::make_tuple("MULTIPOLYGON (((0 0,0 0,0 1,0 1,1 1,1 1,0 0)))",
     264             :                             "MULTIPOLYGON (((0 0,1 1,1 1,0 1,0 1,0 0,0 0)))",
     265             :                             "MULTIPOLYGON_CW_REPEATED_POINTS"),
     266             :             std::make_tuple("MULTIPOLYGON EMPTY", "MULTIPOLYGON EMPTY",
     267             :                             "MULTIPOLYGON_EMPTY"),
     268             :             std::make_tuple("POINT (1 2)", "POINT (1 2)", "POINT"),
     269           1 :         };
     270             :     }
     271             : };
     272             : 
     273          15 : TEST_P(OGRWKBFixupCounterClockWiseExternalRingFixture, test)
     274             : {
     275           7 :     const char *pszInput = std::get<0>(GetParam());
     276           7 :     const char *pszExpected = std::get<1>(GetParam());
     277             : 
     278           7 :     OGRGeometry *poGeom = nullptr;
     279           7 :     ASSERT_EQ(OGRGeometryFactory::createFromWkt(pszInput, nullptr, &poGeom),
     280             :               OGRERR_NONE);
     281           7 :     ASSERT_TRUE(poGeom != nullptr);
     282           7 :     std::vector<GByte> abyWkb(poGeom->WkbSize());
     283           7 :     poGeom->exportToWkb(wkbNDR, abyWkb.data());
     284           7 :     OGRWKBFixupCounterClockWiseExternalRing(abyWkb.data(), abyWkb.size());
     285           7 :     delete poGeom;
     286           7 :     poGeom = nullptr;
     287           7 :     OGRGeometryFactory::createFromWkb(abyWkb.data(), nullptr, &poGeom);
     288           7 :     ASSERT_TRUE(poGeom != nullptr);
     289           7 :     char *pszWKT = nullptr;
     290           7 :     poGeom->exportToWkt(&pszWKT, wkbVariantIso);
     291           7 :     EXPECT_STREQ(pszWKT, pszExpected);
     292           7 :     CPLFree(pszWKT);
     293           7 :     delete poGeom;
     294             : }
     295             : 
     296          16 : INSTANTIATE_TEST_SUITE_P(
     297             :     test_ogr_wkb, OGRWKBFixupCounterClockWiseExternalRingFixture,
     298             :     ::testing::ValuesIn(
     299             :         OGRWKBFixupCounterClockWiseExternalRingFixture::GetTupleValues()),
     300             :     [](const ::testing::TestParamInfo<
     301             :         OGRWKBFixupCounterClockWiseExternalRingFixture::ParamType> &l_info)
     302             :     { return std::get<2>(l_info.param); });
     303             : 
     304             : class OGRWKBIntersectsPessimisticFixture
     305             :     : public test_ogr_wkb,
     306             :       public ::testing::WithParamInterface<std::tuple<
     307             :           const char *, double, double, double, double, bool, const char *>>
     308             : {
     309             :   public:
     310             :     static std::vector<std::tuple<const char *, double, double, double, double,
     311             :                                   bool, const char *>>
     312           1 :     GetTupleValues()
     313             :     {
     314             :         return {
     315             :             std::make_tuple("POINT(1 2)", 0.9, 1.9, 1.1, 2.1, true, "POINT_IN"),
     316             :             std::make_tuple("POINT(1 2)", 1.05, 1.9, 1.1, 2.1, false,
     317             :                             "POINT_OUT1"),
     318             :             std::make_tuple("POINT(1 2)", 0.9, 2.05, 1.1, 2.1, false,
     319             :                             "POINT_OUT2"),
     320             :             std::make_tuple("POINT(1 2)", 0.9, 1.9, 0.95, 2.1, false,
     321             :                             "POINT_OUT3"),
     322             :             std::make_tuple("POINT(1 2)", 0.9, 1.9, 1.1, 1.95, false,
     323             :                             "POINT_OUT4"),
     324             :             std::make_tuple("POINT Z (1 2 3)", 0.9, 1.9, 1.1, 2.1, true,
     325             :                             "POINTZ_IN"),
     326             :             std::make_tuple("POINT Z (1 2 3)", 1.05, 1.9, 1.1, 2.1, false,
     327             :                             "POINTZ_OUT"),
     328             :             std::make_tuple("POINT EMPTY", 0.9, 1.9, 1.1, 2.1, false,
     329             :                             "POINT_EMPTY"),
     330             :             std::make_tuple("LINESTRING(1 2, 3 4)", 0.9, 1.9, 1.1, 2.1, true,
     331             :                             "LINESTRING_IN"),
     332             :             std::make_tuple("LINESTRING(1 2, 3 4)", 0.9, 1.9, 0.95, 2.1, false,
     333             :                             "LINESTRING_OUT"),
     334             :             std::make_tuple("LINESTRING EMPTY", 0.9, 1.9, 1.1, 2.1, false,
     335             :                             "LINESTRING_EMPTY"),
     336             :             std::make_tuple("LINESTRING Z (1 2 10, 3 4 10)", 0.9, 1.9, 1.1, 2.1,
     337             :                             true, "LINESTRINGZ_IN"),
     338             :             std::make_tuple("LINESTRING Z (1 2 10, 3 4 10)", 0.9, 1.9, 0.95,
     339             :                             2.1, false, "LINESTRINGZ_OUT"),
     340             :             std::make_tuple("POLYGON((1 2,1 3,10 3,1 2))", 0.9, 1.9, 1.1, 2.1,
     341             :                             true, "POLYGON_IN"),
     342             :             std::make_tuple("POLYGON((1 2,1 3,10 3,1 2))", 0.9, 1.9, 0.95, 2.1,
     343             :                             false, "POLYGON_OUT"),
     344             :             std::make_tuple("POLYGON EMPTY", 0.9, 1.9, 1.1, 2.1, false,
     345             :                             "POLYGON_EMPTY"),
     346             :             std::make_tuple("POLYGON Z ((1 2 -10,1 3 -10,10 3 -10,1 2 -10))",
     347             :                             0.9, 1.9, 1.1, 2.1, true, "POLYGONZ_IN"),
     348             :             std::make_tuple("POLYGON Z ((1 2 -10,1 3 -10,10 3 -10,1 2 -10))",
     349             :                             0.9, 1.9, 0.95, 2.1, false, "POLYGONZ_OUT"),
     350             :             std::make_tuple("MULTIPOINT((1 2))", 0.9, 1.9, 1.1, 2.1, true,
     351             :                             "MULTIPOINT_IN"),
     352             :             std::make_tuple("MULTIPOINT((1 2))", 1.05, 1.9, 1.1, 2.1, false,
     353             :                             "MULTIPOINT_OUT1"),
     354             :             std::make_tuple("MULTIPOINT((1 2))", 0.9, 2.05, 1.1, 2.1, false,
     355             :                             "MULTIPOINT_OUT2"),
     356             :             std::make_tuple("MULTIPOINT((1 2))", 0.9, 1.9, 0.95, 2.1, false,
     357             :                             "MULTIPOINT_OUT3"),
     358             :             std::make_tuple("MULTIPOINT((1 2))", 0.9, 1.9, 1.1, 1.95, false,
     359             :                             "MULTIPOINT_OUT4"),
     360             :             std::make_tuple("MULTIPOINT Z ((1 2 3))", 0.9, 1.9, 1.1, 2.1, true,
     361             :                             "MULTIPOINTZ_IN"),
     362             :             std::make_tuple("MULTIPOINT Z ((1 2 3))", 1.05, 1.9, 1.1, 2.1,
     363             :                             false, "MULTIPOINTZ_OUT"),
     364             :             std::make_tuple("MULTIPOINT EMPTY", 0.9, 1.9, 1.1, 2.1, false,
     365             :                             "MULTIPOINT_EMPTY"),
     366             :             std::make_tuple("MULTILINESTRING((1 2, 3 4))", 0.9, 1.9, 1.1, 2.1,
     367             :                             true, "MULTILINESTRING_IN"),
     368             :             std::make_tuple("MULTILINESTRING((1 2, 3 4))", 0.9, 1.9, 0.95, 2.1,
     369             :                             false, "MULTILINESTRING_OUT"),
     370             :             std::make_tuple("MULTILINESTRING EMPTY", 0.9, 1.9, 1.1, 2.1, false,
     371             :                             "MULTILINESTRING_EMPTY"),
     372             :             std::make_tuple("MULTILINESTRING Z ((1 2 10, 3 4 10))", 0.9, 1.9,
     373             :                             1.1, 2.1, true, "MULTILINESTRINGZ_IN"),
     374             :             std::make_tuple("MULTILINESTRING Z ((1 2 10, 3 4 10))", 0.9, 1.9,
     375             :                             0.95, 2.1, false, "MULTILINESTRINGZ_OUT"),
     376             :             std::make_tuple("MULTIPOLYGON(((1 2,1 3,10 3,1 2)))", 0.9, 1.9, 1.1,
     377             :                             2.1, true, "MULTIPOLYGON_IN"),
     378             :             std::make_tuple("MULTIPOLYGON(((1 2,1 3,10 3,1 2)))", 0.9, 1.9,
     379             :                             0.95, 2.1, false, "MULTIPOLYGON_OUT"),
     380             :             std::make_tuple("MULTIPOLYGON EMPTY", 0.9, 1.9, 1.1, 2.1, false,
     381             :                             "MULTIPOLYGON_EMPTY"),
     382             :             std::make_tuple(
     383             :                 "MULTIPOLYGON Z (((1 2 -10,1 3 -10,10 3 -10,1 2 -10)))", 0.9,
     384             :                 1.9, 1.1, 2.1, true, "MULTIPOLYGONZ_IN"),
     385             :             std::make_tuple(
     386             :                 "MULTIPOLYGON Z (((1 2 -10,1 3 -10,10 3 -10,1 2 -10)))", 0.9,
     387             :                 1.9, 0.95, 2.1, false, "MULTIPOLYGONZ_OUT"),
     388             :             std::make_tuple("GEOMETRYCOLLECTION(POINT(1 2))", 0.9, 1.9, 1.1,
     389             :                             2.1, true, "GEOMETRYCOLLECTION_POINT_IN"),
     390             :             std::make_tuple("CIRCULARSTRING(0 10,1 11,2 10)", -0.1, 9.9, 0.1,
     391             :                             10.1, true, "CIRCULARSTRING_IN"),
     392             :             std::make_tuple("CIRCULARSTRING(0 10,1 11,2 10)", -0.1, 9.9, -0.05,
     393             :                             10.1, false, "CIRCULARSTRING_OUT"),
     394             :             std::make_tuple("CIRCULARSTRING EMPTY", -0.1, 9.9, 0.1, 10.1, false,
     395             :                             "CIRCULARSTRING_EMPTY"),
     396             :             std::make_tuple("TRIANGLE((1 2,1 3,10 3,1 2))", 0.9, 1.9, 1.1, 2.1,
     397             :                             true, "TRIANGLE_IN"),
     398             :             std::make_tuple("TRIANGLE((1 2,1 3,10 3,1 2))", 0.9, 1.9, 0.95, 2.1,
     399             :                             false, "TRIANGLE_OUT"),
     400             :             std::make_tuple("TRIANGLE EMPTY", 0.9, 1.9, 1.1, 2.1, false,
     401             :                             "TRIANGLE_EMPTY"),
     402             :             std::make_tuple("TRIANGLE Z ((1 2 -10,1 3 -10,10 3 -10,1 2 -10))",
     403             :                             0.9, 1.9, 1.1, 2.1, true, "TRIANGLEZ_IN"),
     404             :             std::make_tuple("TRIANGLE Z ((1 2 -10,1 3 -10,10 3 -10,1 2 -10))",
     405             :                             0.9, 1.9, 0.95, 2.1, false, "TRIANGLEZ_OUT"),
     406             :             std::make_tuple("COMPOUNDCURVE((1 2, 3 4))", 0.9, 1.9, 1.1, 2.1,
     407             :                             true, "COMPOUNDCURVE_IN"),
     408             :             std::make_tuple("COMPOUNDCURVE((1 2, 3 4))", 0.9, 1.9, 0.95, 2.1,
     409             :                             false, "COMPOUNDCURVE_OUT"),
     410             :             std::make_tuple("COMPOUNDCURVE EMPTY", 0.9, 1.9, 1.1, 2.1, false,
     411             :                             "COMPOUNDCURVE_EMPTY"),
     412             :             std::make_tuple("COMPOUNDCURVE Z ((1 2 10, 3 4 10))", 0.9, 1.9, 1.1,
     413             :                             2.1, true, "COMPOUNDCURVEZ_IN"),
     414             :             std::make_tuple("COMPOUNDCURVE Z ((1 2 10, 3 4 10))", 0.9, 1.9,
     415             :                             0.95, 2.1, false, "COMPOUNDCURVEZ_OUT"),
     416             :             std::make_tuple("CURVEPOLYGON((1 2,1 3,10 3,1 2))", 0.9, 1.9, 1.1,
     417             :                             2.1, true, "CURVEPOLYGON_IN"),
     418             :             std::make_tuple("CURVEPOLYGON((1 2,1 3,10 3,1 2))", 0.9, 1.9, 0.95,
     419             :                             2.1, false, "CURVEPOLYGON_OUT"),
     420             :             std::make_tuple("CURVEPOLYGON EMPTY", 0.9, 1.9, 1.1, 2.1, false,
     421             :                             "CURVEPOLYGON_EMPTY"),
     422             :             std::make_tuple(
     423             :                 "CURVEPOLYGON Z ((1 2 -10,1 3 -10,10 3 -10,1 2 -10))", 0.9, 1.9,
     424             :                 1.1, 2.1, true, "CURVEPOLYGONZ_IN"),
     425             :             std::make_tuple(
     426             :                 "CURVEPOLYGON Z ((1 2 -10,1 3 -10,10 3 -10,1 2 -10))", 0.9, 1.9,
     427             :                 0.95, 2.1, false, "CURVEPOLYGONZ_OUT"),
     428             :             std::make_tuple("MULTICURVE((1 2, 3 4))", 0.9, 1.9, 1.1, 2.1, true,
     429             :                             "MULTICURVE_IN"),
     430             :             std::make_tuple("MULTICURVE((1 2, 3 4))", 0.9, 1.9, 0.95, 2.1,
     431             :                             false, "MULTICURVE_OUT"),
     432             :             std::make_tuple("MULTICURVE EMPTY", 0.9, 1.9, 1.1, 2.1, false,
     433             :                             "MULTICURVE_EMPTY"),
     434             :             std::make_tuple("MULTICURVE Z ((1 2 10, 3 4 10))", 0.9, 1.9, 1.1,
     435             :                             2.1, true, "MULTICURVEZ_IN"),
     436             :             std::make_tuple("MULTICURVE Z ((1 2 10, 3 4 10))", 0.9, 1.9, 0.95,
     437             :                             2.1, false, "MULTICURVEZ_OUT"),
     438             :             std::make_tuple("MULTISURFACE(((1 2,1 3,10 3,1 2)))", 0.9, 1.9, 1.1,
     439             :                             2.1, true, "MULTISURFACE_IN"),
     440             :             std::make_tuple("MULTISURFACE(((1 2,1 3,10 3,1 2)))", 0.9, 1.9,
     441             :                             0.95, 2.1, false, "MULTISURFACE_OUT"),
     442             :             std::make_tuple("MULTISURFACE EMPTY", 0.9, 1.9, 1.1, 2.1, false,
     443             :                             "MULTISURFACE_EMPTY"),
     444             :             std::make_tuple(
     445             :                 "MULTISURFACE Z (((1 2 -10,1 3 -10,10 3 -10,1 2 -10)))", 0.9,
     446             :                 1.9, 1.1, 2.1, true, "MULTISURFACEZ_IN"),
     447             :             std::make_tuple(
     448             :                 "MULTISURFACE Z (((1 2 -10,1 3 -10,10 3 -10,1 2 -10)))", 0.9,
     449             :                 1.9, 0.95, 2.1, false, "MULTISURFACEZ_OUT"),
     450             :             std::make_tuple("POLYHEDRALSURFACE(((1 2,1 3,10 3,1 2)))", 0.9, 1.9,
     451             :                             1.1, 2.1, true, "POLYHEDRALSURFACE_IN"),
     452             :             std::make_tuple("POLYHEDRALSURFACE(((1 2,1 3,10 3,1 2)))", 0.9, 1.9,
     453             :                             0.95, 2.1, false, "POLYHEDRALSURFACE_OUT"),
     454             :             std::make_tuple("POLYHEDRALSURFACE EMPTY", 0.9, 1.9, 1.1, 2.1,
     455             :                             false, "POLYHEDRALSURFACE_EMPTY"),
     456             :             std::make_tuple(
     457             :                 "POLYHEDRALSURFACE Z (((1 2 -10,1 3 -10,10 3 -10,1 2 -10)))",
     458             :                 0.9, 1.9, 1.1, 2.1, true, "POLYHEDRALSURFACEZ_IN"),
     459             :             std::make_tuple(
     460             :                 "POLYHEDRALSURFACE Z (((1 2 -10,1 3 -10,10 3 -10,1 2 -10)))",
     461             :                 0.9, 1.9, 0.95, 2.1, false, "POLYHEDRALSURFACEZ_OUT"),
     462             :             std::make_tuple("TIN(((1 2,1 3,10 3,1 2)))", 0.9, 1.9, 1.1, 2.1,
     463             :                             true, "TIN_IN"),
     464             :             std::make_tuple("TIN(((1 2,1 3,10 3,1 2)))", 0.9, 1.9, 0.95, 2.1,
     465             :                             false, "TIN_OUT"),
     466             :             std::make_tuple("TIN EMPTY", 0.9, 1.9, 1.1, 2.1, false,
     467             :                             "TIN_EMPTY"),
     468             :             std::make_tuple("TIN Z (((1 2 -10,1 3 -10,10 3 -10,1 2 -10)))", 0.9,
     469             :                             1.9, 1.1, 2.1, true, "TINZ_IN"),
     470             :             std::make_tuple("TIN Z (((1 2 -10,1 3 -10,10 3 -10,1 2 -10)))", 0.9,
     471             :                             1.9, 0.95, 2.1, false, "TINZ_OUT"),
     472           1 :         };
     473             :     }
     474             : };
     475             : 
     476         151 : TEST_P(OGRWKBIntersectsPessimisticFixture, test)
     477             : {
     478          75 :     const char *pszInput = std::get<0>(GetParam());
     479          75 :     const double dfMinX = std::get<1>(GetParam());
     480          75 :     const double dfMinY = std::get<2>(GetParam());
     481          75 :     const double dfMaxX = std::get<3>(GetParam());
     482          75 :     const double dfMaxY = std::get<4>(GetParam());
     483          75 :     const bool bIntersects = std::get<5>(GetParam());
     484             : 
     485          75 :     OGRGeometry *poGeom = nullptr;
     486          75 :     EXPECT_EQ(OGRGeometryFactory::createFromWkt(pszInput, nullptr, &poGeom),
     487             :               OGRERR_NONE);
     488          75 :     ASSERT_TRUE(poGeom != nullptr);
     489         150 :     std::vector<GByte> abyWkb(poGeom->WkbSize());
     490          75 :     poGeom->exportToWkb(wkbNDR, abyWkb.data(), wkbVariantIso);
     491          75 :     delete poGeom;
     492          75 :     OGREnvelope sEnvelope;
     493          75 :     sEnvelope.MinX = dfMinX;
     494          75 :     sEnvelope.MinY = dfMinY;
     495          75 :     sEnvelope.MaxX = dfMaxX;
     496          75 :     sEnvelope.MaxY = dfMaxY;
     497          75 :     EXPECT_EQ(
     498             :         OGRWKBIntersectsPessimistic(abyWkb.data(), abyWkb.size(), sEnvelope),
     499             :         bIntersects);
     500             : 
     501          75 :     if (abyWkb.size() > 9)
     502             :     {
     503          62 :         EXPECT_EQ(OGRWKBIntersectsPessimistic(abyWkb.data(), 9, sEnvelope),
     504             :                   false);
     505             : 
     506          62 :         if (!STARTS_WITH(pszInput, "POINT"))
     507             :         {
     508             :             // Corrupt number of sub-geometries
     509          54 :             abyWkb[5] = 0xff;
     510          54 :             abyWkb[6] = 0xff;
     511          54 :             abyWkb[7] = 0xff;
     512          54 :             abyWkb[8] = 0xff;
     513          54 :             EXPECT_EQ(OGRWKBIntersectsPessimistic(abyWkb.data(), abyWkb.size(),
     514             :                                                   sEnvelope),
     515             :                       false);
     516             :         }
     517             :     }
     518             : }
     519             : 
     520         152 : INSTANTIATE_TEST_SUITE_P(
     521             :     test_ogr_wkb, OGRWKBIntersectsPessimisticFixture,
     522             :     ::testing::ValuesIn(OGRWKBIntersectsPessimisticFixture::GetTupleValues()),
     523             :     [](const ::testing::TestParamInfo<
     524             :         OGRWKBIntersectsPessimisticFixture::ParamType> &l_info)
     525             :     { return std::get<6>(l_info.param); });
     526             : 
     527             : }  // namespace

Generated by: LCOV version 1.14