// Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test // Copyright (c) 2010-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_BUFFER_HPP #define BOOST_GEOMETRY_TEST_BUFFER_HPP #define BOOST_GEOMETRY_DEBUG_WITH_MAPPER #define TEST_WITH_SVG #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include //#include //#include #include #include //#include //#include #include #include #if defined(TEST_WITH_SVG) # include #endif #include template void post_map(Geometry const& geometry, Mapper& mapper) { typedef bg::detail::overlay::turn_info < typename bg::point_type::type > turn_info; std::vector turns; bg::detail::self_get_turn_points::no_interrupt_policy policy; bg::self_turns < bg::detail::overlay::assign_null_policy >(geometry, turns, policy); BOOST_FOREACH(turn_info const& turn, turns) { mapper.map(turn.point, "fill:rgb(255,128,0);stroke:rgb(0,0,100);stroke-width:1", 3); } } template < typename GeometryOut, template < typename , typename #if defined(BOOST_GEOMETRY_DEBUG_WITH_MAPPER) , typename #endif > class JoinStrategy, typename Geometry > void test_buffer(std::string const& caseid, Geometry const& geometry, char join, double expected_area, double distance_left, double distance_right) { namespace bg = boost::geometry; typedef typename bg::coordinate_type::type coordinate_type; typedef typename bg::point_type::type point_type; typedef bg::strategy::buffer::distance_assymetric distance; typedef typename bg::ring_type::type ring_type; std::ostringstream filename; filename << "buffer_" << (bg::geometry_id::value == 2 ? "line" : "poly") << "_" << caseid << "_" << string_from_type::name() << "_" << join << ".svg"; std::ofstream svg(filename.str().c_str()); bg::svg_mapper mapper(svg, 500, 500); { bg::model::box box; bg::envelope(geometry, box); double d = distance_left; if (distance_right > 0) { d += distance_right; } bg::buffer(box, box, d * 1.1); mapper.add(box); } typedef JoinStrategy < point_type, typename bg::point_type::type #ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER , bg::svg_mapper #endif > join_strategy_type; #ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER join_strategy_type join_strategy(mapper); #else join_strategy_type join_strategy; #endif std::vector buffered; #ifdef BOOST_GEOMETRY_TEST_BUFFER_POLYGON { GeometryOut buffered_step1; bg::detail::buffer::polygon_buffer < Geometry, GeometryOut, join_strategy_type >::apply(geometry, buffered_step1, distance_left, join_strategy #ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER , mapper #endif ); buffered.push_back(buffered_step1); } #else { typedef bg::strategy::buffer::distance_assymetric distance; typedef bg::detail::buffer::intersecting_inserter < std::vector > inserter_type; inserter_type inserter(buffered); bg::detail::buffer::linestring_buffer < Geometry, GeometryOut, distance, join_strategy_type >::apply(geometry, inserter, distance(distance_left, distance_left / 2.0), join_strategy #ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER , mapper #endif ); } #endif //std::cout << caseid << std::endl; //std::cout << "INPUT: " << bg::wkt(geometry) << std::endl; //std::cout << "OUTPUT:" << std::endl; //BOOST_FOREACH(GeometryOut const& polygon, buffered) //{ // std::cout << bg::wkt(polygon) << std::endl; //} // Map input geometry in green mapper.map(geometry, "opacity:0.5;fill:rgb(0,128,0);stroke:rgb(0,128,0);stroke-width:1"); BOOST_FOREACH(GeometryOut const& polygon, buffered) { mapper.map(polygon, "opacity:0.8;fill:none;stroke:rgb(0,0,0);stroke-width:2"); post_map(polygon, mapper); } } #ifdef BOOST_GEOMETRY_CHECK_WITH_POSTGIS static int counter = 0; #endif template < typename Geometry, template < typename , typename #if defined(BOOST_GEOMETRY_DEBUG_WITH_MAPPER) , typename #endif > class JoinStrategy, typename GeometryOut > void test_one(std::string const& caseid, std::string const& wkt, char join, double expected_area, double distance_left, double distance_right = -999) { namespace bg = boost::geometry; Geometry g; bg::read_wkt(wkt, g); typedef typename bg::point_type::type point_type; //std::cout << caseid << std::endl; if (join == 'm') { //return; } #ifdef BOOST_GEOMETRY_CHECK_WITH_POSTGIS std::cout << (counter > 0 ? "union " : "") << "select " << counter++ << ", '" << caseid << "' as caseid" << ", ST_Area(ST_Buffer(ST_GeomFromText('" << wkt << "'), " << distance_left << ", 'endcap=flat join=" << (join == 'm' ? "miter" : "round") << "'))" << ", " << expected_area << std::endl; #endif test_buffer (caseid, g, join, expected_area, distance_left, distance_right); } #endif