diff --git a/test/algorithms/buffer/CMakeLists.txt b/test/algorithms/buffer/CMakeLists.txt index bb9108509..4f0c84ad3 100644 --- a/test/algorithms/buffer/CMakeLists.txt +++ b/test/algorithms/buffer/CMakeLists.txt @@ -29,6 +29,8 @@ endforeach() foreach(item IN ITEMS buffer_point_geo buffer_polygon_geo + buffer_linestring + buffer_linestring_geo buffer_multi_linestring_geo buffer_multi_polygon_geo buffer_geo_spheroid @@ -41,8 +43,6 @@ endforeach() # Besides that, the buffer_countries test requires the WKT files. foreach(item IN ITEMS buffer_countries - buffer_linestring - buffer_linestring_geo ) boost_geometry_add_unit_test("algorithms" ${item} "not_run") target_compile_definitions(${BOOST_GEOMETRY_UNIT_TEST_NAME} PRIVATE BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) diff --git a/test/algorithms/buffer/buffer_linestring_geo.cpp b/test/algorithms/buffer/buffer_linestring_geo.cpp index 1c16e9723..d919cab39 100644 --- a/test/algorithms/buffer/buffer_linestring_geo.cpp +++ b/test/algorithms/buffer/buffer_linestring_geo.cpp @@ -22,6 +22,10 @@ static std::string const sharp = "LINESTRING(10.3939684 63.4255808, 10.3948159 6 // Linestring forwards and backwards (close to 180 corner) static std::string const opposite = "LINESTRING(10.4000988 63.4283885,10.4029694 63.4280726,10.4006988 63.4283397)"; +namespace +{ + constexpr int points_per_circle = 360; +} template void test_linestring() @@ -31,7 +35,6 @@ void test_linestring() // Because areas can change significantly when another formula is used, // use a high tolerance. - int const points_per_circle = 360; ut_settings settings(0.5); #if defined(BOOST_GEOMETRY_TEST_FAILURES) @@ -71,11 +74,32 @@ void test_linestring() test_one_geo("opposite_miter", opposite, strategy, side, circle, join_miter, end_flat, 1705.0, 5.0, specific); test_one_geo("opposite_miter25", opposite, strategy, side, circle, join_miter25, end_flat, 1642.0, 5.0, specific); } +} +template +void test_linestring_aimes() +{ + using coordinate_type = bg::coordinate_type_t; + using linestring = bg::model::linestring; + using polygon = bg::model::polygon; + + constexpr coordinate_type distance_meters = 25.0; + + // Because areas can change significantly when another formula is used, + // use a high tolerance. + ut_settings settings(0.5); settings.test_area = false; - int const n = sizeof(testcases_aimes) / sizeof(testcases_aimes[0]); - // Cases (ouf of 197) where the guessed area estimations are not met. + bg::strategies::buffer::geographic strategy; + bg::strategy::buffer::geographic_side_straight side; + bg::strategy::buffer::geographic_join_miter join_miter; + bg::strategy::buffer::geographic_join_miter join_miter25(2.5); + bg::strategy::buffer::geographic_join_round join_round(points_per_circle); + bg::strategy::buffer::geographic_end_round end_round(points_per_circle); + bg::strategy::buffer::geographic_point_circle circle(points_per_circle); + bg::strategy::buffer::end_flat end_flat; + + // There are cases where some estimations are not met. // If this needs to be changed, be sure to // inspect the result visually on SVG or CSV (QGis). @@ -85,60 +109,60 @@ void test_linestring() std::set const curved_cases_min_area{86, 181}; // Cases which are curved such that the max area is larger than expected. std::set const curved_cases_max_area{5, 95, 119, 142}; - // Cases which are rounded such that it results in a large area - std::set const round_cases_max_area{}; - // Cases which are not yet valid or false negatives - std::set const round_cases_invalid{}; - for (auto i = 0; i < n; i++) +#if defined(BOOST_GEOMETRY_TEST_FAILURES) + std::set const skip_cases_round_round{}; + std::set const skip_cases_round_flat{}; + std::set const skip_cases_miter_flat{}; +#else + // Cases where the algorithm is still failing. + std::set const skip_cases_round_round{17, 22, 38, 181, 196}; + std::set const skip_cases_round_flat{17, 22, 38, 103, 196}; + std::set const skip_cases_miter_flat{17, 18, 22, 38, 103, 196}; +#endif + + for (auto const& enumerated : bg::util::enumerate(testcases_aimes)) { + auto const index = enumerated.index; + auto const& test_case = enumerated.value; + settings.multiplier_min_area - = curved_cases_min_area.count(i) > 0 ? 0.85 + = curved_cases_min_area.count(index) > 0 ? 0.85 : ut_settings().multiplier_min_area; settings.multiplier_max_area - = curved_cases_max_area.count(i) > 0 ? 1.2 - : round_cases_max_area.count(i) > 0 ? 1.5 + = curved_cases_max_area.count(index) > 0 ? 1.2 : ut_settings().multiplier_max_area; settings.fraction_buffered_points_too_close - = cases_with_artefacts.count(i) > 0 ? 0.20 + = cases_with_artefacts.count(index) > 0 ? 0.20 : ut_settings().fraction_buffered_points_too_close; // With miter/flat, the artefacts are more pronounced and there can // be more points close than expected. - auto settings_mf = settings; - settings_mf.fraction_buffered_points_too_close *= 4.0; + auto settings_miter_flat = settings; + settings_miter_flat.fraction_buffered_points_too_close *= 4.0; // With rounded cases, both rounded ends overap, adapt the expected area - auto settings_rr = settings; - settings_rr.multiplier_min_area - = round_cases_max_area.count(i) > 0 ? 0.75 - : settings.multiplier_min_area; + auto settings_round_round = settings; + settings_round_round.multiplier_min_area = settings.multiplier_min_area; - settings_rr.set_test_validity(round_cases_invalid.count(i) == 0); - -#if ! defined(BOOST_GEOMETRY_TEST_FAILURES) - if (i == 143 || i == 196) + std::string const caseid = "aimes_" + std::to_string(index); + if (skip_cases_round_round.count(index) == 0) { - continue; + test_one_geo(caseid + "_rr", test_case, + strategy, side, circle, join_round, end_round, -1, distance_meters, settings_round_round); } - if (i == 75) + if (skip_cases_round_flat.count(index) == 0) { - // One regression - continue; + test_one_geo(caseid + "_rf", test_case, + strategy, side, circle, join_round, end_flat, -1, distance_meters, settings); + } + if (skip_cases_miter_flat.count(index) == 0) + { + test_one_geo(caseid + "_mf", test_case, + strategy, side, circle, join_miter, end_flat, -1, distance_meters, settings_miter_flat); } - // Old message: - // 181 fails, it should generate a hole, but instead that is the outer ring now. - -#endif - - test_one_geo("aimes_" + std::to_string(i) + "_rr", testcases_aimes[i], - strategy, side, circle, join_round, end_round, -1, 25.0, settings_rr); - test_one_geo("aimes_" + std::to_string(i) + "_rf", testcases_aimes[i], - strategy, side, circle, join_round, end_flat, -1, 25.0, settings); - test_one_geo("aimes_" + std::to_string(i) + "_mf", testcases_aimes[i], - strategy, side, circle, join_miter, end_flat, -1, 25.0, settings_mf); } } @@ -149,6 +173,8 @@ int test_main(int, char* []) test_linestring > >(); test_linestring > >(); + test_linestring_aimes > >(); + #if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) test_linestring > >(); #endif