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

Generated by: LCOV version 1.14