// Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test // Copyright (c) 2007-2012 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) #ifndef BOOST_GEOMETRY_TEST_SIMPLIFY_HPP #define BOOST_GEOMETRY_TEST_SIMPLIFY_HPP // Test-functionality, shared between single and multi tests #include #include #include #include #include #include #include #include #include #include template < typename GeometryForTag, typename Tag = typename bg::tag::type > struct test_equality { template static void apply(Geometry const& geometry, Expected const& expected) { // Verify both spatially equal AND number of points, because several // of the tests only check explicitly on collinear points being // simplified away bool const result = bg::equals(geometry, expected) && bg::num_points(geometry) == bg::num_points(expected); BOOST_CHECK_MESSAGE(result, " result: " << bg::wkt(geometry) << " " << bg::area(geometry) << " expected: " << bg::wkt(expected) << " " << bg::area(expected)); } }; // Linestring does NOT yet have "geometry::equals" implemented // Until then, WKT's are compared (which is acceptable for linestrings, but not // for polygons, because simplify might rotate them) template struct test_equality { template static void apply(Geometry const& geometry, Expected const& expected) { std::ostringstream out1, out2; out1 << bg::wkt(geometry); out2 << bg::wkt(expected); BOOST_CHECK_EQUAL(out1.str(), out2.str()); } }; template struct test_inserter { template static void apply(Geometry& , Expected const& , double ) {} }; template <> struct test_inserter { template static void apply(Geometry& geometry, Expected const& expected, DistanceMeasure const& distance) { { Geometry simplified; bg::detail::simplify::simplify_insert(geometry, std::back_inserter(simplified), distance); test_equality::apply(simplified, expected); } #ifdef TEST_PULL89 { typedef typename bg::point_type::type point_type; typedef typename bg::strategy::distance::detail::projected_point_ax<>::template result_type::type distance_type; typedef bg::strategy::distance::detail::projected_point_ax_less less_comparator; distance_type max_distance(distance); less_comparator less(max_distance); bg::strategy::simplify::detail::douglas_peucker < point_type, bg::strategy::distance::detail::projected_point_ax<>, less_comparator > strategy(less); Geometry simplified; bg::detail::simplify::simplify_insert(geometry, std::back_inserter(simplified), max_distance, strategy); test_equality::apply(simplified, expected); } #endif } }; template void check_geometry(Geometry const& geometry, Expected const& expected, DistanceMeasure const& distance) { Geometry simplified; bg::simplify(geometry, simplified, distance); test_equality::apply(simplified, expected); } template void check_geometry(Geometry const& geometry, Expected const& expected, DistanceMeasure const& distance, Strategy const& strategy) { Geometry simplified; bg::simplify(geometry, simplified, distance, strategy); test_equality::apply(simplified, expected); } template void check_geometry_with_area(Geometry const& geometry, double expected_area, DistanceMeasure const& distance) { Geometry simplified; bg::simplify(geometry, simplified, distance); BOOST_CHECK_CLOSE(bg::area(simplified), expected_area, 0.01); } template void test_geometry(std::string const& wkt, std::string const& expected_wkt, DistanceMeasure distance) { typedef typename bg::point_type::type point_type; Geometry geometry, expected; bg::read_wkt(wkt, geometry); bg::read_wkt(expected_wkt, expected); boost::variant v(geometry); // Define default strategy for testing typedef bg::strategy::simplify::douglas_peucker < typename bg::point_type::type, bg::strategy::distance::projected_point > dp; check_geometry(geometry, expected, distance); check_geometry(v, expected, distance); BOOST_CONCEPT_ASSERT( (bg::concepts::SimplifyStrategy) ); check_geometry(geometry, expected, distance, dp()); check_geometry(v, expected, distance, dp()); // Check inserter (if applicable) test_inserter < typename bg::tag::type >::apply(geometry, expected, distance); #ifdef TEST_PULL89 // Check using non-default less comparator in douglass_peucker typedef typename bg::strategy::distance::detail::projected_point_ax<>::template result_type::type distance_type; typedef bg::strategy::distance::detail::projected_point_ax_less less_comparator; distance_type const max_distance(distance); less_comparator const less(max_distance); typedef bg::strategy::simplify::detail::douglas_peucker < point_type, bg::strategy::distance::detail::projected_point_ax<>, less_comparator > douglass_peucker_with_less; BOOST_CONCEPT_ASSERT( (bg::concepts::SimplifyStrategy) ); check_geometry(geometry, expected, distance, douglass_peucker_with_less(less)); check_geometry(v, expected, distance, douglass_peucker_with_less(less)); #endif } template void test_geometry(std::string const& wkt, std::string const& expected_wkt, DistanceMeasure const& distance, Strategy const& strategy) { Geometry geometry, expected; bg::read_wkt(wkt, geometry); bg::read_wkt(expected_wkt, expected); bg::correct_closure(geometry); bg::correct_closure(expected); boost::variant v(geometry); BOOST_CONCEPT_ASSERT( (bg::concepts::SimplifyStrategy::type>) ); check_geometry(geometry, expected, distance, strategy); check_geometry(v, expected, distance, strategy); } template void test_geometry(std::string const& wkt, double expected_area, DistanceMeasure const& distance) { Geometry geometry; bg::read_wkt(wkt, geometry); bg::correct_closure(geometry); check_geometry_with_area(geometry, expected_area, distance); } #endif