Merge pull request #1120 from vissarion/fix/buffer_tests

Fix buffer tests by using more accurate area computation
This commit is contained in:
Vissarion Fisikopoulos 2023-03-31 10:51:24 +03:00 committed by GitHub
commit a1ecf6a511
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 17 deletions

View File

@ -37,7 +37,7 @@ void test_gc()
bg::strategy::buffer::join_round join;
bg::strategy::buffer::end_round end;
bg::strategy::buffer::point_circle circle;
mpo_t result_mpo;
bg::buffer(gc, result_mpo, distance, side, join, end, circle);

View File

@ -2,6 +2,8 @@
// Unit Test
// Copyright (c) 2022 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@ -16,6 +18,38 @@ namespace
std::string const torg = "POINT(10.3937759 63.4302323)";
}
template
<
typename FormulaPolicy,
typename Spheroid,
typename CalculationType
>
struct geo_buffer_accurate_area
: public bg::strategies::buffer::geographic<FormulaPolicy, Spheroid, CalculationType>
{
using base_t = bg::strategies::buffer::geographic<FormulaPolicy, Spheroid, CalculationType>;
public:
geo_buffer_accurate_area() = default;
explicit geo_buffer_accurate_area(Spheroid const& spheroid)
: base_t(spheroid)
{}
template <typename Geometry>
auto area(Geometry const&,
std::enable_if_t<! bg::util::is_box<Geometry>::value> * = nullptr) const
{
return bg::strategy::area::geographic
<
bg::strategy::karney,
bg::strategy::default_order<bg::strategy::karney>::value,
Spheroid, CalculationType
>(base_t::m_spheroid);
}
};
template <typename Formula, bool Clockwise, typename Point, typename Spheroid>
void test_linestring(std::string const& label, Spheroid const& spheroid,
double expected_area_round, double expected_area_miter)
@ -25,7 +59,9 @@ void test_linestring(std::string const& label, Spheroid const& spheroid,
ut_settings settings(0.1);
bg::strategies::buffer::geographic<Formula, Spheroid> strategy(spheroid);
using CT = typename bg::coordinate_type<Point>::type;
geo_buffer_accurate_area<Formula, Spheroid, CT> strategy(spheroid);
bg::strategy::buffer::geographic_side_straight<Formula, Spheroid> side(spheroid);
bg::strategy::buffer::geographic_join_miter<Formula, Spheroid> join_miter(spheroid);
bg::strategy::buffer::geographic_join_round<Formula, Spheroid> join_round(spheroid, points_per_circle);
@ -45,7 +81,9 @@ void test_point(std::string const& label, Spheroid const& spheroid, double expec
ut_settings settings(0.01);
bg::strategies::buffer::geographic<Formula, Spheroid> strategy(spheroid);
using CT = typename bg::coordinate_type<Point>::type;
geo_buffer_accurate_area<Formula, Spheroid, CT> strategy(spheroid);
bg::strategy::buffer::geographic_point_circle<Formula, Spheroid> circle(spheroid, points_per_circle);
// All are ignored for points
@ -57,24 +95,31 @@ void test_point(std::string const& label, Spheroid const& spheroid, double expec
test_one_geo<Point, polygon>(label, torg, strategy, side, circle, join_round, end_round, expected_area, 100.0, settings);
}
int test_main(int, char* [])
template <typename test_type>
void test_all()
{
BoostGeometryWriteTestConfiguration();
using test_type = default_test_type;
using point_t = bg::model::point<test_type, 2, bg::cs::geographic<bg::degree>>;
using strategy = bg::strategy::andoyer;
// Use the default spheroid
bg::srs::spheroid<test_type> def_spheroid;
test_linestring<bg::strategy::andoyer, true, point_t>("line_def", def_spheroid, 7996.0, 8093.0);
test_point<bg::strategy::andoyer, true, point_t>("point_def", def_spheroid, 31450.0);
test_linestring<strategy, true, point_t>("line_def", def_spheroid, 8046.26, 8143.37);
test_point<strategy, true, point_t>("point_def", def_spheroid, 31414.36);
// Call it with a quite different spheroid (a near sphere), this changes internal geographic calculations
// and should result in different areas. Using CSV creation, it's visible in QGis.
bg::srs::spheroid<test_type> alt_spheroid(6378000.0, 6375000.0);
test_linestring<bg::strategy::andoyer, true, point_t>("line_alt", alt_spheroid, 8097.0, 8115.3);
test_point<bg::strategy::andoyer, true, point_t>("point_alt", alt_spheroid, 31409.0);
test_linestring<strategy, true, point_t>("line_alt", alt_spheroid, 8030.53, 8127.61);
test_point<strategy, true, point_t>("point_alt", alt_spheroid, 31414.33);
}
int test_main(int, char* [])
{
BoostGeometryWriteTestConfiguration();
// There are several issues with float type such as invalid geometries as output and assertion fails
//test_all<float>();
test_all<default_test_type>();
return 0;
}

View File

@ -37,7 +37,7 @@ static std::string const mysql_2015_04_10a = "MULTILINESTRING((-58 19, 61 88),(1
static std::string const mysql_2015_04_10b = "MULTILINESTRING((-58 19, 61 88), (-63 -5, -262141 -536870908, -3 87, 77 -69))";
static std::string const mysql_2015_09_08a = "MULTILINESTRING((7 -4, -3 -5), (72057594037927936 15, 72057594037927940 70368744177660, 32771 36028797018963964, 8589934589 2305843009213693953, 7 2, 9.300367e+307 9.649737e+307, -4092 -274877906946, 5 10, -3 4))";
static std::string const mysql_2015_09_08b = "MULTILINESTRING((-9 -10, 0 -1, 5 -10, -6 7, -7 7, 5.041061e+307 9.926906e+307, 6.870356e+307 1.064454e+307, 35184372088830 288230376151711743, 183673728842483250000000000000000000000.000000 244323751784861950000000000000000000000.000000), (-23530 -7131, -6 1, 1 1, 2 -6, 32766 -4194302, -4 -6), (134217725 0, 50336782742294697000000000000000000000.000000 36696596077212901000000000000000000000.000000, 7434 16486, 3.025467e+307 8.926790e+307), (2147483646 67108868, 71328904281592545000000000000000000000.000000 225041650340452780000000000000000000000.000000, -7 4, 1.667154e+307 3.990414e+307))";
static std::string const mysql_2015_09_08b = "MULTILINESTRING((-9 -10, 0 -1, 5 -10, -6 7, -7 7, 5.041061e+307 9.926906e+307, 6.870356e+307 1.064454e+307, 35184372088830 288230376151711743, 183673728842483250000000000000000000000.000000 244323751784861950000000000000000000000.000000), (-23530 -7131, -6 1, 1 1, 2 -6, 32766 -4194302, -4 -6), (134217725 0, 50336782742294697000000000000000000000.000000 36696596077212901000000000000000000000.000000, 7434 16486, 3.025467e+307 8.926790e+307), (2147483646 67108868, 71328904281592545000000000000000000000.000000 225041650340452780000000000000000000000.000000, -7 4, 1.667154e+307 3.990414e+307))";
static std::string const mysql_23023665_1 = "MULTILINESTRING((-5 15, 7 15, 19 -10, -11 -2),(2 13, 2 -9))";

View File

@ -47,7 +47,7 @@ std::string select_within_box(const std::string& wkt, const std::string& wkt_box
geometry.erase(geometry.begin(), geometry.begin() + 1);
}
geometry.erase(std::remove_if(boost::begin(geometry), boost::end(geometry),
geometry.erase(std::remove_if(boost::begin(geometry), boost::end(geometry),
[&poly](const auto& p) { return ! bg::within(p, poly); }), boost::end(geometry));
std::ostringstream out;
@ -77,7 +77,7 @@ void test_geometry(const std::string& base_folder, bool test_all = false, bool g
if (generate_cases)
{
const std::string gr = read_from_wkt_file<multi_polygon>(base_folder + "gr_ll.wkt");
test_one_geo<multi_polygon, polygon>("gr", gr, strategy, _s, _c, join, _e, 222719122493.0, 10000.0, settings);
std::cout << "cyclades = " << select_within_box<multi_polygon>(gr, "BOX(24.1395 36.0147,26.1382 38.1464)") << std::endl;
@ -85,7 +85,7 @@ void test_geometry(const std::string& base_folder, bool test_all = false, bool g
std::cout << "dodecaneses = " << select_within_box<multi_polygon>(gr, "BOX(25.8740 35.1906,28.4227 38.0700)") << std::endl;
std::cout << "ionians = " << select_within_box<multi_polygon>(gr, "BOX(18.9540 37.2072,22.4337 40.6295)") << std::endl;
std::cout << "crete = " << select_within_box<multi_polygon>(gr, "BOX(23.0592 34.4105,26.5606 35.9347)") << std::endl;
std::cout << "aegeans = " << aegeans << std::endl;
}

View File

@ -156,7 +156,7 @@ struct ut_settings : public ut_base_settings
// Number of points in a circle. Not used for geo tests.
int points_per_circle;
double multiplier_min_area = 0.95;
double multiplier_max_area = 1.05;
double fraction_buffered_points_too_close = 0.10;