LCOV - code coverage report
Current view: top level - autotest/cpp - test_marching_squares_square.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 233 233 100.0 %
Date: 2024-05-13 13:33:37 Functions: 58 58 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * $Id$
       3             :  *
       4             :  * Project:  GDAL algorithms
       5             :  * Purpose:  Tests for the marching squares algorithm
       6             :  * Author:   Hugo Mercier, <hugo dot mercier at oslandia dot com>
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2018, Hugo Mercier, <hugo dot mercier at oslandia dot com>
      10             :  *
      11             :  * Permission is hereby granted, free of charge, to any person obtaining a
      12             :  * copy of this software and associated documentation files (the "Software"),
      13             :  * to deal in the Software without restriction, including without limitation
      14             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15             :  * and/or sell copies of the Software, and to permit persons to whom the
      16             :  * Software is furnished to do so, subject to the following conditions:
      17             :  *
      18             :  * The above copyright notice and this permission notice shall be included
      19             :  * in all copies or substantial portions of the Software.
      20             :  *
      21             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27             :  * DEALINGS IN THE SOFTWARE.
      28             :  ****************************************************************************/
      29             : 
      30             : #include "gdal_unit_test.h"
      31             : 
      32             : #include "gdal_alg.h"
      33             : 
      34             : #include "marching_squares/square.h"
      35             : #include "marching_squares/level_generator.h"
      36             : #include <vector>
      37             : #include <map>
      38             : #include <fstream>
      39             : 
      40             : #include "gtest_include.h"
      41             : 
      42             : namespace test_marching_squares_square
      43             : {
      44             : using namespace marching_squares;
      45             : 
      46             : struct Writer
      47             : {
      48             :     typedef std::pair<Point, Point> Segment;
      49             : 
      50           6 :     void addSegment(int levelIdx, const Point &first, const Point &second)
      51             :     {
      52           6 :         contours[levelIdx].push_back(Segment(first, second));
      53           6 :     }
      54             : 
      55          11 :     void addBorderSegment(int levelIdx, const Point &first, const Point &second)
      56             :     {
      57          11 :         borders[levelIdx].push_back(Segment(first, second));
      58          11 :     }
      59             : 
      60             :     std::map<int, std::vector<Segment>> contours;
      61             :     std::map<int, std::vector<Segment>> borders;
      62             :     const bool polygonize = true;
      63             : };
      64             : 
      65             : // Common fixture with test data
      66             : struct test_ms_square : public ::testing::Test
      67             : {
      68             : };
      69             : 
      70             : // Dummy test
      71           4 : TEST_F(test_ms_square, dummy)
      72             : {
      73             :     {
      74           1 :         const double levels[] = {0, 4};
      75           1 :         FixedLevelRangeIterator levelGenerator(levels, 2);
      76           1 :         auto r = levelGenerator.range(0, 5.0);
      77           1 :         auto b = r.begin();
      78           1 :         EXPECT_EQ((*b).first, 1);
      79           1 :         EXPECT_EQ((*b).second, 4.0);
      80           1 :         auto e = r.end();
      81           1 :         EXPECT_EQ((*e).first, 2);
      82           1 :         EXPECT_EQ((*e).second, Inf);
      83             :     }
      84             :     {
      85           1 :         IntervalLevelRangeIterator levelGenerator(0, 4);
      86           1 :         auto r = levelGenerator.range(0, 5.0);
      87           1 :         auto b = r.begin();
      88           1 :         EXPECT_EQ((*b).first, 1);
      89           1 :         EXPECT_EQ((*b).second, 4.0);
      90           1 :         auto e = r.end();
      91           1 :         EXPECT_EQ((*e).first, 2);
      92           1 :         EXPECT_EQ((*e).second, 8.0);
      93             :     }
      94             :     {
      95           1 :         IntervalLevelRangeIterator levelGenerator(0, 10);
      96           1 :         auto r = levelGenerator.range(-18, 5.0);
      97           1 :         auto b = r.begin();
      98           1 :         EXPECT_EQ((*b).first, -1);
      99           1 :         EXPECT_EQ((*b).second, -10.0);
     100           1 :         auto e = r.end();
     101           1 :         EXPECT_EQ((*e).first, 1);
     102           1 :         EXPECT_EQ((*e).second, 10.0);
     103             :     }
     104             :     {
     105           1 :         ExponentialLevelRangeIterator levelGenerator(2);
     106           1 :         auto r = levelGenerator.range(0, 5.0);
     107           1 :         auto b = r.begin();
     108           1 :         EXPECT_EQ((*b).first, 1);
     109           1 :         EXPECT_EQ((*b).second, 1.0);
     110           1 :         ++b;
     111           1 :         EXPECT_EQ((*b).first, 2);
     112           1 :         EXPECT_EQ((*b).second, 2.0);
     113           1 :         ++b;
     114           1 :         EXPECT_EQ((*b).first, 3);
     115           1 :         EXPECT_EQ((*b).second, 4.0);
     116           1 :         auto e = r.end();
     117           1 :         EXPECT_EQ((*e).first, 4);
     118           1 :         EXPECT_EQ((*e).second, 8.0);
     119             :     }
     120           1 : }
     121             : 
     122           4 : TEST_F(test_ms_square, only_zero)
     123             : {
     124             :     // Square with only 0, level = 0.1
     125           1 :     Square square(ValuedPoint(0, 1, 0), ValuedPoint(1, 1, 0),
     126           2 :                   ValuedPoint(0, 0, 0), ValuedPoint(1, 0, 0));
     127           1 :     Square::Segments segments(square.segments(.1));
     128             :     //
     129             :     //   0                    0
     130             :     //    +------------------+
     131             :     //    |                  |
     132             :     //    |                  |
     133             :     //    |                  |
     134             :     //    |                  |
     135             :     //    |                  |
     136             :     //    |                  |
     137             :     //    |                  |
     138             :     //    +------------------+
     139             :     //   0                    0
     140           1 :     EXPECT_EQ(segments.size(), size_t(0));
     141           1 : }
     142             : 
     143           4 : TEST_F(test_ms_square, only_one)
     144             : {
     145             :     // Square with only 1, level = 0.1
     146           1 :     Square square(ValuedPoint(0, 1, 1), ValuedPoint(1, 1, 1),
     147           2 :                   ValuedPoint(0, 0, 1), ValuedPoint(1, 0, 1));
     148             :     //
     149             :     //   1                    1
     150             :     //    +------------------+
     151             :     //    |                  |
     152             :     //    |                  |
     153             :     //    |                  |
     154             :     //    |                  |
     155             :     //    |                  |
     156             :     //    |                  |
     157             :     //    |                  |
     158             :     //    +------------------+
     159             :     //   1                    1
     160           1 :     Square::Segments segments(square.segments(.1));
     161           1 :     EXPECT_EQ(segments.size(), size_t(0));
     162           1 : }
     163             : 
     164           4 : TEST_F(test_ms_square, only_zero_level_1)
     165             : {
     166             :     // Square with only 1, level = 1.0
     167           1 :     Square square(ValuedPoint(0, 1, 1), ValuedPoint(1, 1, 1),
     168           2 :                   ValuedPoint(0, 0, 1), ValuedPoint(1, 0, 1));
     169             :     //
     170             :     //   1                    1
     171             :     //    +------------------+
     172             :     //    |                  |
     173             :     //    |                  |
     174             :     //    |                  |
     175             :     //    |                  |
     176             :     //    |                  |
     177             :     //    |                  |
     178             :     //    |                  |
     179             :     //    +------------------+
     180             :     //   1                    1
     181           1 :     Square::Segments segments(square.segments(1.0));
     182           1 :     EXPECT_EQ(segments.size(), size_t(0));
     183           1 : }
     184             : 
     185           4 : TEST_F(test_ms_square, one_segment)
     186             : {
     187             :     // Square with one segment, level = 0.1
     188           1 :     Square square(ValuedPoint(0, 1, 1), ValuedPoint(1, 1, 0),
     189           2 :                   ValuedPoint(0, 0, 0), ValuedPoint(1, 0, 0));
     190             :     //
     191             :     //   0                    0
     192             :     //    +------------------+
     193             :     //    |                  |
     194             :     //    |                  |
     195             :     //    |                  |
     196             :     //    |                  |
     197             :     //    |                  |
     198             :     //    o                  |
     199             :     //    | \                |
     200             :     //    +---o--------------+
     201             :     //   1                    0
     202           1 :     Square::Segments segments(square.segments(.1));
     203           1 :     EXPECT_EQ(segments.size(), size_t(1));
     204           1 :     EXPECT_TRUE(segments[0].first == Point(.9, 1));
     205           1 :     EXPECT_TRUE(segments[0].second == Point(0, .1));
     206           1 : }
     207             : 
     208           4 : TEST_F(test_ms_square, fudge_test_1)
     209             : {
     210             :     // Fudge test 1
     211           1 :     Square square(ValuedPoint(0, 1, 0), ValuedPoint(1, 1, 1),
     212           2 :                   ValuedPoint(0, 0, 1), ValuedPoint(1, 0, 1));
     213             :     //
     214             :     //   0                    1
     215             :     //    +------------------o
     216             :     //    |               __/|
     217             :     //    |            __/   |
     218             :     //    |         __/      |
     219             :     //    |       _/         |
     220             :     //    |    __/           |
     221             :     //    | __/              |
     222             :     //    |/                 |
     223             :     //    o------------------+
     224             :     //   1                    1
     225             :     //  (0,0)
     226             :     {
     227           1 :         Square::Segments segments(square.segments(0.0));
     228           1 :         EXPECT_EQ(segments.size(), size_t(0));
     229             :     }
     230             :     {
     231           1 :         Square::Segments segments(square.segments(1.0));
     232           1 :         EXPECT_EQ(segments.size(), size_t(1));
     233           1 :         EXPECT_NEAR(segments[0].first.x, 0.0, 0.001);
     234           1 :         EXPECT_NEAR(segments[0].first.y, 0.0, 0.001);
     235           1 :         EXPECT_NEAR(segments[0].second.x, 1.0, 0.001);
     236           1 :         EXPECT_NEAR(segments[0].second.y, 1.0, 0.001);
     237             :     }
     238           1 : }
     239             : 
     240           4 : TEST_F(test_ms_square, fudge_test_2)
     241             : {
     242             :     // Fudge test 2
     243           1 :     Square square(ValuedPoint(0, 1, 1), ValuedPoint(1, 1, 0),
     244           2 :                   ValuedPoint(0, 0, 0), ValuedPoint(1, 0, 0));
     245             :     //
     246             :     //   1                    0
     247             :     //    +o-----------------+
     248             :     //    o+                 |
     249             :     //    |                  |
     250             :     //    |                  |
     251             :     //    |                  |
     252             :     //    |                  |
     253             :     //    |                  |
     254             :     //    |                  |
     255             :     //    +------------------+
     256             :     //   0                    0
     257             :     // (0,0)
     258             :     {
     259           1 :         Square::Segments segments(square.segments(1.0));
     260           1 :         EXPECT_EQ(segments.size(), 1);
     261           1 :         EXPECT_NEAR(segments[0].first.x, 0.0, 0.001);
     262           1 :         EXPECT_NEAR(segments[0].first.y, 1.0, 0.001);
     263           1 :         EXPECT_NEAR(segments[0].second.x, 0.0, 0.001);
     264           1 :         EXPECT_NEAR(segments[0].second.y, 1.0, 0.001);
     265             :     }
     266             :     {
     267           1 :         Square::Segments segments(square.segments(0.0));
     268           1 :         EXPECT_EQ(segments.size(), 0);
     269             :     }
     270           1 : }
     271             : 
     272           4 : TEST_F(test_ms_square, nan)
     273             : {
     274             :     // A square with NaN
     275           1 :     const Square square(ValuedPoint(2.500000, 1.500000, 224.990005),
     276           1 :                         ValuedPoint(3.500000, 1.500000, NaN),
     277           1 :                         ValuedPoint(2.500000, 2.500000, 225.029999),
     278           2 :                         ValuedPoint(3.500000, 2.500000, 224.770004));
     279             : 
     280             :     //
     281             :     // 224.990005            NaN
     282             :     //    +------------------+
     283             :     //    |                  |
     284             :     //    |                  |
     285             :     //    |                  |
     286             :     //    |                  |
     287             :     //    |                  |
     288             :     //    |                  |
     289             :     //    |                  |
     290             :     //    +------------------+
     291             :     // 225.029999     224.770004
     292             : 
     293           1 :     const Square ul(square.upperLeftSquare());
     294           1 :     const Square ll(square.lowerLeftSquare());
     295             : 
     296             :     // upper left and lower left squares
     297             :     //
     298             :     // 224.990005 224.990005 NaN
     299             :     //    +--------+---------+
     300             :     //    |        |         |
     301             :     //    |        |         |
     302             :     //    |        |         |
     303             :     //    +--------+  224.930002
     304             :     // 225.010002  |         |
     305             :     //    |        |         |
     306             :     //    |    224.900001    |
     307             :     //    +--------+---------+
     308             :     // 225.029999     224.770004
     309             : 
     310           1 :     EXPECT_NEAR(ul.lowerLeft.value, 225.010002, 0.000001);
     311           1 :     EXPECT_NEAR(ul.lowerRight.value, 224.930002, 0.000001);
     312           1 :     EXPECT_NEAR(ul.upperRight.value, 224.990005, 0.000001);
     313           1 :     EXPECT_NEAR(ll.lowerRight.value, 224.900001, 0.000001);
     314             : 
     315           1 :     EXPECT_EQ(ul.lowerLeft.x, ll.upperLeft.x);
     316           1 :     EXPECT_EQ(ul.lowerLeft.y, ll.upperLeft.y);
     317           1 :     EXPECT_EQ(ul.lowerLeft.value, ll.upperLeft.value);
     318             : 
     319           1 :     EXPECT_EQ(ul.lowerRight.x, ll.upperRight.x);
     320           1 :     EXPECT_EQ(ul.lowerRight.y, ll.upperRight.y);
     321           1 :     EXPECT_EQ(ul.lowerRight.value, ll.upperRight.value);
     322             : 
     323           1 :     const Square::Segments segments_up(ul.segments(225));
     324           1 :     const Square::Segments segments_down(ll.segments(225));
     325             : 
     326             :     // segments on 225
     327             :     //
     328             :     // 224.990005 224.990005 NaN
     329             :     //    <--------<---------+
     330             :     //    |        |         |
     331             :     //    o_       |         |
     332             :     //    | \      |         |
     333             :     //    >--o-----<  224.930002
     334             :     // 225.01|002  |         |
     335             :     //    |  \     |         |
     336             :     //    |   |224.900001    |
     337             :     //    >---o----<---------+
     338             :     // 225.029999     224.770004
     339             : 
     340           1 :     EXPECT_EQ(segments_up.size(), 1);
     341           1 :     EXPECT_EQ(segments_down.size(), 1);
     342             : 
     343             :     // the two segments have a point in common
     344           1 :     EXPECT_EQ(segments_up[0].second, segments_down[0].first);
     345           1 : }
     346             : 
     347           4 : TEST_F(test_ms_square, border_test_1)
     348             : {
     349             :     // Border test 1
     350           1 :     const Square square(ValuedPoint(0.5, 0.5, NaN), ValuedPoint(1.5, 0.5, NaN),
     351           1 :                         ValuedPoint(0.5, 1.5, 272.87),
     352           2 :                         ValuedPoint(1.5, 1.5, 272.93));
     353             :     //
     354             :     //   NaN                NaN
     355             :     //    +------------------+
     356             :     //    |                  |
     357             :     //    |                  |
     358             :     //    |                  |
     359             :     //    |                  |
     360             :     //    |                  |
     361             :     //    |                  |
     362             :     //    |                  |
     363             :     //    +------------------+
     364             :     // 272.87             272.93
     365           1 :     const Square ll(square.lowerLeftSquare());
     366           1 :     const Square lr(square.lowerRightSquare());
     367             : 
     368             :     //
     369             :     //   NaN                NaN
     370             :     //    +------------------+
     371             :     //    |                  |
     372             :     //    |                  |
     373             :     // 272.87   272.90000 272.93
     374             :     //    +--------+---------+
     375             :     //    |        |         |
     376             :     //    |        |         |
     377             :     //    |        |         |
     378             :     //    +--------+---------+
     379             :     // 272.87   272.90000 272.93
     380             : 
     381           1 :     Square::Segments segments_l(ll.segments(272.9));
     382           1 :     Square::Segments segments_r(lr.segments(272.9));
     383             : 
     384             :     // the level falls exactly on corners
     385             :     // thanks to the fudge, each corner should be shifted away a bit
     386             : 
     387             :     //
     388             :     //   NaN                NaN
     389             :     //    +------------------+
     390             :     //    |                  |
     391             :     //    |                  |
     392             :     // 272.87   272.90000 272.93
     393             :     //    <-------o>--------->
     394             :     //    |       :|         |
     395             :     //    |       :|         |
     396             :     //    |       :|         |
     397             :     //    <-------o>--------->
     398             :     // 272.87   272.90000 272.93
     399             : 
     400           1 :     EXPECT_EQ(segments_l.size(), size_t(1));
     401           1 :     EXPECT_EQ(segments_r.size(), size_t(0));
     402           1 : }
     403             : 
     404           4 : TEST_F(test_ms_square, multiple_levels)
     405             : {
     406             :     // Multiple levels
     407             :     const Square square(
     408           1 :         ValuedPoint(0.5, 1.5, 272.99), ValuedPoint(1.5, 1.5, NaN),
     409           2 :         ValuedPoint(0.5, 0.5, 273.03), ValuedPoint(1.5, 0.5, 272.9));
     410             :     //
     411             :     // 272.99               NaN
     412             :     //    +------------------+
     413             :     //    |                  |
     414             :     //    |                  |
     415             :     //    |                  |
     416             :     //    |                  |
     417             :     //    |                  |
     418             :     //    |                  |
     419             :     //    |                  |
     420             :     //    +------------------+
     421             :     // 273.03             272.90
     422             : 
     423           1 :     const Square ul(square.upperLeftSquare());
     424             : 
     425             :     //
     426             :     // 272.99   272.99      NaN
     427             :     //    +---------+--------+
     428             :     //    |         |        |
     429             :     //    |         |        |
     430             :     //    |         |        |
     431             :     //    +---------+        |
     432             :     // 273.01    272.97      |
     433             :     //    |                  |
     434             :     //    |                  |
     435             :     //    +------------------+
     436             :     // 273.03             272.90
     437           1 :     EXPECT_TRUE((std::fabs(ul.lowerLeft.value - 273.01) < 0.01));
     438           1 :     EXPECT_TRUE((std::fabs(ul.lowerRight.value - 272.97) < 0.01));
     439           1 :     EXPECT_TRUE((std::fabs(ul.upperRight.value - 272.99) < 0.01));
     440             : 
     441             :     // We have a NaN value on the right, we should then have a right border
     442           1 :     EXPECT_TRUE((ul.borders == Square::RIGHT_BORDER));
     443             : 
     444           2 :     Writer writer;
     445             :     // levels starting at min and increasing by 0.1
     446           1 :     IntervalLevelRangeIterator levelGenerator(0, .1);
     447             : 
     448           1 :     ul.process(levelGenerator, writer);
     449             : 
     450             :     // we only have a contour when level = 273.0
     451             :     // (0.5, 1.5)                  (1.5, 1.5)
     452             :     //      272.99   272.99      NaN
     453             :     //         +---------+--------+
     454             :     //         |         ||       |
     455             :     //         o         ||       |
     456             :     //         |\        ||       |
     457             :     //         +-o-------+        |
     458             :     //      273.01    272.97      |
     459             :     //         |                  |
     460             :     //         |                  |
     461             :     //         +------------------+
     462             :     //      273.03             272.90
     463             :     // (0.5, 0.5)                  (1.5, 0.5)
     464             : 
     465           1 :     EXPECT_TRUE((writer.contours.size() == 2));
     466           1 :     EXPECT_TRUE((writer.borders.size() == 1));
     467           1 :     EXPECT_TRUE((writer.contours.find(2730) != writer.contours.end()));
     468           1 :     EXPECT_TRUE((writer.contours.find(2731) != writer.contours.end()));
     469           1 :     EXPECT_TRUE((writer.borders.find(2730) != writer.borders.end()));
     470             :     // we have one segment border on the right
     471           1 :     EXPECT_TRUE((writer.borders[2730].size() == 1));
     472           1 :     EXPECT_TRUE((writer.contours[2730].size() == 1));
     473           1 :     EXPECT_TRUE((writer.contours[2731].size() == 1));
     474           1 : }
     475             : 
     476           4 : TEST_F(test_ms_square, border_test_3)
     477             : {
     478             :     // Border test 3
     479           1 :     Square square(ValuedPoint(0, 0, 10), ValuedPoint(1, 0, 5),
     480           2 :                   ValuedPoint(0, 1, NaN), ValuedPoint(1, 1, 4));
     481             :     // level value = 7
     482             :     //   10        7.5        5
     483             :     //    +---------+--------+
     484             :     //    |         |        |
     485             :     //    |        _o        |
     486             :     //    |      _/ |        |
     487             :     // 10 +====o====+ 6.33   |
     488             :     //    |                  |
     489             :     //    |                  |
     490             :     //    |                  |
     491             :     //    +------------------+
     492             :     //   NaN                  4
     493           1 :     const Square ul(square.upperLeftSquare());
     494             :     // "Lower left value",
     495           1 :     EXPECT_TRUE((std::fabs(ul.lowerLeft.value - 10.00) < 0.01));
     496             :     // "Lower right value",
     497           1 :     EXPECT_TRUE((std::fabs(ul.lowerRight.value - 6.33) < 0.01));
     498             :     // "Upper right value",
     499           1 :     EXPECT_TRUE((std::fabs(ul.upperRight.value - 7.50) < 0.01));
     500             : 
     501             :     // We have a NaN value on the right, we should then have a right border
     502             :     // "We have the lower border",
     503           1 :     EXPECT_TRUE(ul.borders == Square::LOWER_BORDER);
     504             : 
     505             :     {
     506             :         // ... with a level interval
     507           2 :         Writer writer;
     508           1 :         IntervalLevelRangeIterator levelGenerator(7, 5);
     509           1 :         ul.process(levelGenerator, writer);
     510             : 
     511             :         // we have one contour at 7 and 12
     512             :         // and two borders: one, at 7 and the second at >7 (12)
     513             :         // "We have 2 borders",
     514           1 :         EXPECT_EQ(writer.borders.size(), size_t(2));
     515             :         // "We have 2 contours",
     516           1 :         EXPECT_EQ(writer.contours.size(), size_t(2));
     517             : 
     518             :         // "Border at 0",
     519           1 :         EXPECT_TRUE(writer.borders.find(0) != writer.borders.end());
     520             :         // "Border at 1",
     521           1 :         EXPECT_TRUE(writer.borders.find(1) != writer.borders.end());
     522             :         // "No contour at 0",
     523           1 :         EXPECT_TRUE(writer.contours.find(0) != writer.contours.end());
     524             :         // and we have one contour and 2 borders
     525             :         // "1 contour at 0",
     526           1 :         EXPECT_EQ(writer.contours[0].size(), size_t(1));
     527             :         // "1 border at 0",
     528           1 :         EXPECT_EQ(writer.borders[0].size(), size_t(1));
     529             :         // "1 border at 1",
     530           1 :         EXPECT_EQ(writer.borders[1].size(), size_t(1));
     531             :         // the border at 7.0 is around 0.5, 0.5
     532             :         // "Border at 1 is around 0.5, 0.5",
     533           1 :         EXPECT_TRUE((writer.borders[0][0].first.x == 0.5 &&
     534             :                      writer.borders[0][0].first.y == 0.5) ||
     535             :                     (writer.borders[0][0].second.x == 0.5 &&
     536             :                      writer.borders[0][0].second.y == 0.5));
     537             :         // the border at 12.0 is around 0, 0.5
     538             :         // "Border at 1 is around 0, 0.5",
     539           1 :         EXPECT_TRUE((writer.borders[1][0].first.x == 0.0 &&
     540             :                      writer.borders[1][0].first.y == 0.5) ||
     541             :                     (writer.borders[1][0].second.x == 0.0 &&
     542             :                      writer.borders[1][0].second.y == 0.5));
     543             :     }
     544             : 
     545             :     // test with a fixed set of levels
     546             :     {
     547           2 :         Writer writer;
     548           2 :         std::vector<double> levels = {7.0};
     549           1 :         FixedLevelRangeIterator levelGenerator(&levels[0], 1);
     550           1 :         ul.process(levelGenerator, writer);
     551             : 
     552             :         // we have one contour at 7 and 12
     553             :         // and two borders: one, at 7 and the second at >7 (12)
     554             :         // "We have 2 borders",
     555           1 :         EXPECT_EQ(writer.borders.size(), size_t(2));
     556             :         // "We have 2 contours",
     557           1 :         EXPECT_EQ(writer.contours.size(), size_t(2));
     558             : 
     559             :         // "Border at 0",
     560           1 :         EXPECT_TRUE(writer.borders.find(0) != writer.borders.end());
     561             :         // "Border at 1",
     562           1 :         EXPECT_TRUE(writer.borders.find(1) != writer.borders.end());
     563             :         // "No contour at 0",
     564           1 :         EXPECT_TRUE(writer.contours.find(0) != writer.contours.end());
     565             :         // and we have one contour and 2 borders
     566             :         // "1 contour at 0",
     567           1 :         EXPECT_EQ(writer.contours[0].size(), size_t(1));
     568             :         // "1 border at 0",
     569           1 :         EXPECT_EQ(writer.borders[0].size(), size_t(1));
     570             :         // "1 border at 1",
     571           1 :         EXPECT_EQ(writer.borders[1].size(), size_t(1));
     572             :         // the border at 7.0 is around 0.5, 0.5
     573             :         // "Border at 1 is around 0.5, 0.5",
     574           1 :         EXPECT_TRUE((writer.borders[0][0].first.x == 0.5 &&
     575             :                      writer.borders[0][0].first.y == 0.5) ||
     576             :                     (writer.borders[0][0].second.x == 0.5 &&
     577             :                      writer.borders[0][0].second.y == 0.5));
     578             :         // the border at 12.0 is around 0, 0.5
     579             :         // "Border at 1 is around 0, 0.5",
     580           1 :         EXPECT_TRUE((writer.borders[1][0].first.x == 0.0 &&
     581             :                      writer.borders[1][0].first.y == 0.5) ||
     582             :                     (writer.borders[1][0].second.x == 0.0 &&
     583             :                      writer.borders[1][0].second.y == 0.5));
     584             :     }
     585           1 : }
     586             : 
     587           4 : TEST_F(test_ms_square, level_value_below_square_values)
     588             : {
     589             :     // Test level value below square values
     590           1 :     Square square(ValuedPoint(0, 0, 10), ValuedPoint(1, 0, 5),
     591           2 :                   ValuedPoint(0, 1, 8), ValuedPoint(1, 1, 4));
     592             :     // level value = 2
     593             :     //   10                   5
     594             :     //    +------------------+
     595             :     //    |                  |
     596             :     //    |                  |
     597             :     //    |                  |
     598             :     //    |                  |
     599             :     //    |                  |
     600             :     //    |                  |
     601             :     //    |                  |
     602             :     //    +------------------+
     603             :     //    8                   4
     604             :     {
     605           2 :         Writer writer;
     606           2 :         std::vector<double> levels = {2.0};
     607           1 :         FixedLevelRangeIterator levelGenerator(&levels[0], 1);
     608           1 :         square.process(levelGenerator, writer);
     609           1 :         EXPECT_TRUE((writer.borders.size() == 0));
     610           1 :         EXPECT_TRUE((writer.contours.size() == 0));
     611             :     }
     612           1 : }
     613             : 
     614           4 : TEST_F(test_ms_square, full_border_test_1)
     615             : {
     616             :     // Full border test 1
     617           1 :     Square square(ValuedPoint(-0.5, -0.5, NaN), ValuedPoint(0.5, -0.5, NaN),
     618           2 :                   ValuedPoint(-0.5, 0.5, NaN), ValuedPoint(0.5, 0.5, 5));
     619             :     // level value = 0, 10
     620             :     //   NaN                NaN
     621             :     //    +------------------+
     622             :     //    |                  |
     623             :     //    |                  |
     624             :     //    |                  |
     625             :     //    |                  |
     626             :     //    |                  |
     627             :     //    |                  |
     628             :     //    |                  |
     629             :     //    +------------------+
     630             :     //   NaN                 5
     631             :     {
     632           2 :         Writer writer;
     633           1 :         IntervalLevelRangeIterator levelGenerator(0, 10.0);
     634           1 :         square.process(levelGenerator, writer);
     635           1 :         EXPECT_TRUE((writer.borders.size() == 1));
     636           1 :         EXPECT_TRUE((writer.borders[1].size() == 2));
     637           1 :         EXPECT_TRUE(((writer.borders[1][0].first.x == 0.0 &&
     638             :                       writer.borders[1][0].first.y == 0.0) ||
     639             :                      (writer.borders[1][0].second.x == 0.0 &&
     640             :                       writer.borders[1][0].second.y == 0.0)));
     641           1 :         EXPECT_TRUE(((writer.borders[1][0].first.x == 0.5 &&
     642             :                       writer.borders[1][0].first.y == 0.0) ||
     643             :                      (writer.borders[1][0].second.x == 0.5 &&
     644             :                       writer.borders[1][0].second.y == 0.0)));
     645           1 :         EXPECT_TRUE(((writer.borders[1][1].first.x == 0.0 &&
     646             :                       writer.borders[1][1].first.y == 0.0) ||
     647             :                      (writer.borders[1][1].second.x == 0.0 &&
     648             :                       writer.borders[1][1].second.y == 0.0)));
     649           1 :         EXPECT_TRUE(((writer.borders[1][1].first.x == 0.0 &&
     650             :                       writer.borders[1][1].first.y == 0.0) ||
     651             :                      (writer.borders[1][1].second.x == 0.0 &&
     652             :                       writer.borders[1][1].second.y == 0.5)));
     653             :     }
     654           1 : }
     655             : 
     656           4 : TEST_F(test_ms_square, full_border_test_2)
     657             : {
     658             :     // Full border test 2
     659           1 :     Square square(ValuedPoint(-0.5, -0.5, NaN), ValuedPoint(0.5, -0.5, NaN),
     660           2 :                   ValuedPoint(-0.5, 0.5, NaN), ValuedPoint(0.5, 0.5, 5));
     661             :     // level value = 5.0, 10.0
     662             :     //   NaN                NaN
     663             :     //    +------------------+
     664             :     //    |                  |
     665             :     //    |                  |
     666             :     //    |                  |
     667             :     //    |                  |
     668             :     //    |                  |
     669             :     //    |                  |
     670             :     //    |                  |
     671             :     //    +------------------+
     672             :     //   NaN                 5
     673             :     {
     674           2 :         Writer writer;
     675           1 :         IntervalLevelRangeIterator levelGenerator(5.0, 5.0);
     676           1 :         square.process(levelGenerator, writer);
     677           1 :         EXPECT_TRUE((writer.borders.size() == 1));
     678           1 :         EXPECT_TRUE((writer.borders[1].size() == 2));
     679           1 :         EXPECT_TRUE(((writer.borders[1][0].first.x == 0.0 &&
     680             :                       writer.borders[1][0].first.y == 0.0) ||
     681             :                      (writer.borders[1][0].second.x == 0.0 &&
     682             :                       writer.borders[1][0].second.y == 0.0)));
     683           1 :         EXPECT_TRUE(((writer.borders[1][0].first.x == 0.5 &&
     684             :                       writer.borders[1][0].first.y == 0.0) ||
     685             :                      (writer.borders[1][0].second.x == 0.5 &&
     686             :                       writer.borders[1][0].second.y == 0.0)));
     687           1 :         EXPECT_TRUE(((writer.borders[1][1].first.x == 0.0 &&
     688             :                       writer.borders[1][1].first.y == 0.0) ||
     689             :                      (writer.borders[1][1].second.x == 0.0 &&
     690             :                       writer.borders[1][1].second.y == 0.0)));
     691           1 :         EXPECT_TRUE(((writer.borders[1][1].first.x == 0.0 &&
     692             :                       writer.borders[1][1].first.y == 0.0) ||
     693             :                      (writer.borders[1][1].second.x == 0.0 &&
     694             :                       writer.borders[1][1].second.y == 0.5)));
     695             :     }
     696             :     {
     697           2 :         Writer writer;
     698           2 :         std::vector<double> levels = {5.0};
     699           1 :         FixedLevelRangeIterator levelGenerator(&levels[0], 1);
     700           1 :         square.process(levelGenerator, writer);
     701           1 :         EXPECT_TRUE((writer.borders.size() == 1));
     702           1 :         EXPECT_TRUE((writer.borders[1].size() == 2));
     703           1 :         EXPECT_TRUE(((writer.borders[1][0].first.x == 0.0 &&
     704             :                       writer.borders[1][0].first.y == 0.0) ||
     705             :                      (writer.borders[1][0].second.x == 0.0 &&
     706             :                       writer.borders[1][0].second.y == 0.0)));
     707           1 :         EXPECT_TRUE(((writer.borders[1][0].first.x == 0.5 &&
     708             :                       writer.borders[1][0].first.y == 0.0) ||
     709             :                      (writer.borders[1][0].second.x == 0.5 &&
     710             :                       writer.borders[1][0].second.y == 0.0)));
     711           1 :         EXPECT_TRUE(((writer.borders[1][1].first.x == 0.0 &&
     712             :                       writer.borders[1][1].first.y == 0.0) ||
     713             :                      (writer.borders[1][1].second.x == 0.0 &&
     714             :                       writer.borders[1][1].second.y == 0.0)));
     715           1 :         EXPECT_TRUE(((writer.borders[1][1].first.x == 0.0 &&
     716             :                       writer.borders[1][1].first.y == 0.0) ||
     717             :                      (writer.borders[1][1].second.x == 0.0 &&
     718             :                       writer.borders[1][1].second.y == 0.5)));
     719             :     }
     720           1 : }
     721             : }  // namespace test_marching_squares_square

Generated by: LCOV version 1.14