mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 13:34:10 +00:00
Fix buffer tests by using more accurate area computation
This commit is contained in:
parent
dfcbb75602
commit
4a6c2b0169
@ -2,6 +2,8 @@
|
|||||||
// Unit Test
|
// Unit Test
|
||||||
|
|
||||||
// Copyright (c) 2022 Barend Gehrels, Amsterdam, the Netherlands.
|
// 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,
|
// Use, modification and distribution is subject to the Boost Software License,
|
||||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
// 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)";
|
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>
|
template <typename Formula, bool Clockwise, typename Point, typename Spheroid>
|
||||||
void test_linestring(std::string const& label, Spheroid const& spheroid,
|
void test_linestring(std::string const& label, Spheroid const& spheroid,
|
||||||
double expected_area_round, double expected_area_miter)
|
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);
|
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_side_straight<Formula, Spheroid> side(spheroid);
|
||||||
bg::strategy::buffer::geographic_join_miter<Formula, Spheroid> join_miter(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);
|
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);
|
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);
|
bg::strategy::buffer::geographic_point_circle<Formula, Spheroid> circle(spheroid, points_per_circle);
|
||||||
|
|
||||||
// All are ignored for points
|
// 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);
|
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 point_t = bg::model::point<test_type, 2, bg::cs::geographic<bg::degree>>;
|
||||||
|
using strategy = bg::strategy::andoyer;
|
||||||
|
|
||||||
// Use the default spheroid
|
// Use the default spheroid
|
||||||
bg::srs::spheroid<test_type> def_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_linestring<strategy, true, point_t>("line_def", def_spheroid, 8046.26, 8143.37);
|
||||||
test_point<bg::strategy::andoyer, true, point_t>("point_def", def_spheroid, 31450.0);
|
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
|
// 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.
|
// 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);
|
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_linestring<strategy, true, point_t>("line_alt", alt_spheroid, 8030.53, 8127.61);
|
||||||
test_point<bg::strategy::andoyer, true, point_t>("point_alt", alt_spheroid, 31409.0);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ struct ut_settings : public ut_base_settings
|
|||||||
|
|
||||||
// Number of points in a circle. Not used for geo tests.
|
// Number of points in a circle. Not used for geo tests.
|
||||||
int points_per_circle;
|
int points_per_circle;
|
||||||
|
|
||||||
double multiplier_min_area = 0.95;
|
double multiplier_min_area = 0.95;
|
||||||
double multiplier_max_area = 1.05;
|
double multiplier_max_area = 1.05;
|
||||||
double fraction_buffered_points_too_close = 0.10;
|
double fraction_buffered_points_too_close = 0.10;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user