Merge branch 'develop' of https://github.com/boostorg/geometry into feature/shortest_points_new_strategies

This commit is contained in:
Vissarion Fisikopoulos
2021-10-06 14:35:06 +03:00
20 changed files with 262 additions and 34 deletions

View File

@@ -212,6 +212,19 @@ void test_all()
}
#endif
{
// This issue was detected for CCW order and only CW is tested by default.
using polygon_ccw = bg::model::polygon<P, ! Clockwise>;
test_one
<
multi_linestring_type, polygon_ccw
>("mysql_33353637_macos11",
"MULTILINESTRING((0 10,10 0),(10 0,0 0),(0 0,10 10))",
bg::strategy::buffer::join_miter(10),
end_round32,
1, 0, 35307.0646,
100.0);
}
}

View File

@@ -96,5 +96,10 @@ int test_main(int, char* [])
test_all<bg::model::point<double, 2, bg::cs::cartesian>>(m, 23);
test_all<bg::model::point<float, 2, bg::cs::cartesian>>(m, 23);
// MP is not a floating point type, therefore approximately_equal
// is behaves as exact and returns only true if they are identical.
// This takes 334 steps (then "d" above is 0.0)
test_all<bg::model::point<mp_test_type, 2, bg::cs::cartesian>>(m, 334);
return 0;
}

View File

@@ -93,7 +93,7 @@ int test_main(int, char* [])
using fp = bg::model::point<float, 2, bg::cs::cartesian>;
using dp = bg::model::point<double, 2, bg::cs::cartesian>;
using ep = bg::model::point<long double, 2, bg::cs::cartesian>;
test_get_clusters<fp>(1.0e-8f);
test_get_clusters<fp>(1.0e-4);
test_get_clusters<dp>(1.0e-13);
test_get_clusters<ep>(1.0e-16);
return 0;

View File

@@ -26,6 +26,27 @@ static std::string case_multi_simplex[2] =
"MULTIPOLYGON(((3 0,0 3,4 5,3 0)))"
};
// To support exact behavior in integer coordinates (rectangular and diagonal)
static std::string case_multi_rectangular[2] =
{
"MULTIPOLYGON(((100 100,100 200,200 200,200 100,100 100)),"
"((300 100,300 200,400 200,400 100,300 100),"
"(325 125,375 125,375 175,325 175,325 125)))",
"MULTIPOLYGON(((150 50,150 150,350 150,350 50,150 50)))"
};
static std::string case_multi_diagonal[2] =
{
"MULTIPOLYGON(((40 0,0 40,40 80,80 40,40 0),(50 20,60 30,50 40,40 30,50 20)))",
"MULTIPOLYGON(((80 0,40 40,80 80,120 40,80 0),(80 30,90 40,80 50,70 40,80 30)))"
};
static std::string case_multi_hard[2] =
{
"MULTIPOLYGON(((0 0,0 4,2 4,2 3,4 3,4 0,0 0)))",
"MULTIPOLYGON(((2 7,4 7,4 2.99959993362426758,2 3,2 7)))"
};
// To mix multi/single
static std::string case_single_simplex = "POLYGON((3 0,0 3,4 5,3 0))";

View File

@@ -24,5 +24,6 @@ test-suite boost-geometry-algorithms-union
[ run union_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
: algorithms_union_multi ]
[ run union_pl_pl.cpp : : : : algorithms_union_pl_pl ]
[ run union_tupled.cpp : : : : algorithms_union_tupled ]
[ run union_tupled.cpp : : : : algorithms_union_tupled ]
[ run union_other_types.cpp : : : : algorithms_union_other_types ]
;

View File

@@ -201,6 +201,10 @@ void test_areal()
TEST_UNION(case_140_multi, 2, 1, -1, 64.953);
TEST_UNION(case_141_multi, 1, 0, -1, 100.0);
TEST_UNION(case_multi_rectangular, 1, 1, -1, 33125);
TEST_UNION(case_multi_diagonal, 1, 2, -1, 5350);
TEST_UNION(case_multi_hard, 1, 0, -1, 22);
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_1",
case_recursive_boxes_1[0], case_recursive_boxes_1[1],
1, 1, 16, 97.0);
@@ -409,7 +413,7 @@ void test_areal()
ticket_12118[0], ticket_12118[1],
1, -1, 27, 2221.38713);
#if defined(BOOST_GEOMETRY_TEST_FAILURES) || ! defined(BOOST_GEOMETRY_USE_RESCALING)
#if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES)
// No output if rescaling is done
test_one<Polygon, MultiPolygon, MultiPolygon>("ticket_12125",
ticket_12125[0], ticket_12125[1],

View File

@@ -0,0 +1,154 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test
// Copyright (c) 2021 Barend Gehrels, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_GEOMETRY_NO_ROBUSTNESS
#include <boost/multiprecision/cpp_bin_float.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <geometry_test_common.hpp>
#include <algorithms/overlay/multi_overlay_cases.hpp>
#include <boost/geometry/algorithms/correct.hpp>
#include <boost/geometry/algorithms/union.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <algorithms/overlay/multi_overlay_cases.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/multi_polygon.hpp>
#include <boost/geometry/util/rational.hpp>
#include <set>
enum class exclude { all, rectangular, diagonal, hard, fp };
template <typename Geometry, typename Expected>
void test_one(std::string const& case_id,
std::string const& wkt1, std::string const& wkt2,
bool debug,
Expected const& expected_area,
Expected const& expected_max = -1)
{
using coor_t = typename bg::coordinate_type<Geometry>::type;
Geometry g1, g2, clip;
bg::read_wkt(wkt1, g1);
bg::read_wkt(wkt2, g2);
bg::correct(g1);
bg::correct(g2);
bg::union_(g1, g2, clip);
auto const area = bg::area(clip);
if (debug)
{
std::cout << "AREA: " << std::setprecision(64) << area
<< " expected " << expected_area
<< " types coordinate " << string_from_type<coor_t>::name()
<< " area " << typeid(decltype(area)).name()
<< " expected " << typeid(Expected).name()
<< " size " << sizeof(coor_t)
<< std::endl;
}
// Check areas, they always have to be specified in integer for this test
// and therefore the checking (including a tolerance) is different
bool const ok = expected_max == -1
? bg::math::equals(area, expected_area)
: bg::math::larger_or_equals(area, expected_area)
&& bg::math::smaller_or_equals(area, expected_max);
BOOST_CHECK_MESSAGE(ok,
"union: " << case_id
<< " area: expected: " << expected_area
<< " detected: " << area
<< " type: " << (string_from_type<coor_t>::name())
<< " (" << (typeid(coor_t).name()) << ")");
}
template <typename Point>
void test_areal(std::set<exclude> const& exclude = {}, bool debug = false)
{
using polygon = bg::model::polygon<Point>;
using multi_polygon = bg::model::multi_polygon<polygon>;
// Intended tests: only 3:
// - simple case having only horizontal/vertical lines ("rectangular")
// - simple case on integer grid but also having diagonals ("diagonal")
// - case going wrong for <float> ("hard")
if (exclude.count(exclude::rectangular)
+ exclude.count(exclude::all) == 0)
{
test_one<multi_polygon>("case_multi_rectangular",
case_multi_rectangular[0], case_multi_rectangular[1], debug, 33125);
}
if (exclude.count(exclude::diagonal)
+ exclude.count(exclude::all) == 0)
{
test_one<multi_polygon>("case_multi_diagonal",
case_multi_diagonal[0], case_multi_diagonal[1], debug, 5350);
}
if (exclude.count(exclude::hard)
+ exclude.count(exclude::fp)
+ exclude.count(exclude::all) == 0)
{
test_one<multi_polygon>("case_multi_hard",
case_multi_hard[0], case_multi_hard[1], debug, 21, 23);
}
}
int test_main(int, char* [])
{
namespace bm = boost::multiprecision;
using bg::model::d2::point_xy;
// Standard floating point types
test_areal<point_xy<float>>({exclude::hard});
test_areal<point_xy<double>>({});
test_areal<point_xy<long double>>({});
// Standard integer types
test_areal<point_xy<std::int16_t>>({exclude::fp});
test_areal<point_xy<std::int32_t>>({exclude::fp});
test_areal<point_xy<std::int64_t>>({exclude::fp});
// Boost multi precision (integer)
test_areal<point_xy<bm::int128_t>>({exclude::fp});
test_areal<point_xy<bm::checked_int128_t>>({exclude::fp});
// Boost multi precision (floating point)
test_areal<point_xy<bm::number<bm::cpp_bin_float<5>>>>();
test_areal<point_xy<bm::number<bm::cpp_bin_float<10>>>>();
test_areal<point_xy<bm::number<bm::cpp_bin_float<50>>>>();
test_areal<point_xy<bm::number<bm::cpp_bin_float<100>>>>();
test_areal<point_xy<bm::number<bm::cpp_dec_float<50>>>>({});
// Boost multi precision (rational)
test_areal<point_xy<bm::cpp_rational>>({exclude::fp});
test_areal<point_xy<bm::checked_cpp_rational>>({exclude::fp});
// Boost multi precision float128 wrapper, is currently NOT supported
// and it is limited to certain compilers anyway
// test_areal<point_xy<bm::float128>>();
// Boost rational (tests compilation)
// (the rectangular case is correct; other input might give wrong results)
// The int16 version throws a <zero denominator> exception
test_areal<point_xy<boost::rational<std::int16_t>>>({exclude::all});
test_areal<point_xy<boost::rational<std::int32_t>>>({exclude::fp});
test_areal<point_xy<boost::rational<std::int64_t>>>({exclude::fp});
return 0;
}