c++boostboost-geometry

Compile errors with boost::geometry::buffer


I want to buffer a linestring and getting some compile errors with boost::geometry::buffer.

I have the code below:

// type definitions
using boost_point = boost::geometry::model::d2::point_xy<double>;
using boost_polygon = boost::geometry::model::polygon<boost_point>;
using boost_multipolygon = boost::geometry::model::multi_polygon<boost_polygon>;

// buffer configurations
const double buffer_distance = 0.5;
const int points_per_circle = 10;
boost::geometry::strategy::buffer::distance_symmetric<double> distance_strategy(buffer_distance);
boost::geometry::strategy::buffer::join_round join_strategy(points_per_circle);
boost::geometry::strategy::buffer::end_round end_strategy(points_per_circle);
boost::geometry::strategy::buffer::point_circle circle_strategy(points_per_circle);
boost::geometry::strategy::buffer::side_straight side_strategy;

// convert 3d polyline to 2d polyline then to boost linestring
std::vector<Eigen::Vector3d> polyline_3d = get_polyline_3d();
std::vector<boost_point> polyline_2d = polyline_3d | 
    ranges::view::transform([](const Eigen::Vector3d &point){return point.head<2>();}) | 
    ranges::view::transform([](const Eigen::Vector2d &point){return boost::geometry::make<boost_point>(point[0], point[1]);}) | 
    ranges::to<std::vector<boost_point>>();
auto ls = boost::geometry::model::linestring<boost_point>(polyline_2d.begin(),polyline_2d.end());

// get a buffered multipolygon from linestring
boost_multipolygon buffered;
boost::geometry::buffer(ls, buffered, distance_strategy, side_strategy, join_strategy, end_strategy, circle_strategy);

I'm getting the following compile errors:

boost/geometry/strategies/distance.hpp:97:5: error: no matching function for call to 'assertion_failed<false>(mpl_::failed************ (boost::geometry::strategy::distance::services::default_strategy<boost::geometry::point_tag, boost::geometry::segment_tag, boost::geometry::model::point<long long int, 2, boost::geometry::cs::cartesian>, boost::geometry::model::point<long long int, 2, boost::geometry::cs::cartesian>, boost::geometry::cartesian_tag, boost::geometry::cartesian_tag, void>::NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE_COMBINATION::************)(mpl_::assert_::types<boost::geometry::model::point<long long int, 2, boost::geometry::cs::cartesian>, boost::geometry::model::point<long long int, 2, boost::geometry::cs::cartesian>, boost::geometry::cartesian_tag, boost::geometry::cartesian_tag>))'
     BOOST_MPL_ASSERT_MSG

boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp:71:13: error: no type named 'type' in 'struct boost::geometry::strategy::distance::services::default_strategy<boost::geometry::point_tag, boost::geometry::segment_tag, boost::geometry::model::d2::point_xy<double>, boost::geometry::model::d2::point_xy<double>, boost::geometry::cartesian_tag, boost::geometry::cartesian_tag, void>'
     >::type ds_strategy_type;
             ^~~~~~~~~~~~~~~~
boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp:75:7: error: no type named 'type' in 'struct boost::geometry::strategy::distance::services::default_strategy<boost::geometry::point_tag, boost::geometry::segment_tag, boost::geometry::model::d2::point_xy<double>, boost::geometry::model::d2::point_xy<double>, boost::geometry::cartesian_tag, boost::geometry::cartesian_tag, void>'
     > strategy_type;
       ^~~~~~~~~~~~~

boost/geometry/strategies/distance.hpp:97:5: error: no matching function for call to 'assertion_failed<false>(mpl_::failed************ (boost::geometry::strategy::distance::services::default_strategy<boost::geometry::point_tag, boost::geometry::segment_tag, boost::geometry::model::point<long long int, 2, boost::geometry::cs::cartesian>, boost::geometry::model::point<long long int, 2, boost::geometry::cs::cartesian>, boost::geometry::cartesian_tag, boost::geometry::cartesian_tag, void>::NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE_COMBINATION::************)(mpl_::assert_::types<boost::geometry::model::point<long long int, 2, boost::geometry::cs::cartesian>, boost::geometry::model::point<long long int, 2, boost::geometry::cs::cartesian>, boost::geometry::cartesian_tag, boost::geometry::cartesian_tag>))'
     BOOST_MPL_ASSERT_MSG

boost/geometry/strategies/comparable_distance_result.hpp:51:8: error: no type named 'type' in 'struct boost::geometry::detail::distance::default_strategy<boost::geometry::model::point<long long int, 2, boost::geometry::cs::cartesian>, boost::geometry::model::referring_segment<const boost::geometry::model::point<long long int, 2, boost::geometry::cs::cartesian> >, boost::geometry::pointlike_tag, boost::geometry::segment_tag, false>'

boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp:884:48: error: no matching function for call to 'comparable_distance(boost::geometry::detail::buffer::buffered_piece_collection<boost::geometry::model::ring<boost::geometry::model::d2::point_xy<double>, true, true, std::vector, std::allocator>, boost::geometry::strategy::intersection::cartesian_segments<>, boost::geometry::detail::robust_policy<boost::geometry::model::d2::point_xy<double>, boost::geometry::model::point<long long int, 2, boost::geometry::cs::cartesian>, double> >::robust_point_type&, robust_segment_type&)'

I think my usage of buffer is pretty basic, and I'm confused why this would be causing so many compile errors. Am I missing something here?


Solution

  • I cannot reproduce this:

    Live On Compiler Explorer

    #include <boost/geometry.hpp>
    #include <boost/geometry/geometries/point_xy.hpp>
    #include <boost/geometry/geometries/multi_polygon.hpp>
    #include <range/v3/all.hpp>
    #include <Eigen/Eigen>
    
    namespace bg = boost::geometry;
    
    // type definitions
    using boost_point        = bg::model::d2::point_xy<double>;
    using boost_polygon      = bg::model::polygon<boost_point>;
    using boost_multipolygon = bg::model::multi_polygon<boost_polygon>;
    
    std::vector<Eigen::Vector3d> get_polyline_3d() { return {}; }
    
    int main()
    {
        using ranges::views::transform;
    
        // convert 3d polyline to 2d polyline then to boost linestring
        std::vector<Eigen::Vector3d> polyline_3d = get_polyline_3d();
        std::vector<boost_point>     polyline_2d =
            polyline_3d //
            | transform([](const Eigen::Vector3d& point) { return point.head<2>(); }) //
            | transform([](const Eigen::Vector2d& point) { return bg::make<boost_point>(point[0], point[1]); }) //
            | ranges::to<std::vector<boost_point>>();
    
        auto ls = bg::model::linestring<boost_point>(polyline_2d.begin(),
                                                     polyline_2d.end());
    
        // get a buffered multipolygon from linestring
        boost_multipolygon buffered;
        {
            // buffer configurations
            const double buffer_distance   = 0.5;
            const int    points_per_circle = 10;
    
            namespace bs = bg::strategy::buffer;
            bs::distance_symmetric<double> distance_strategy(buffer_distance);
            bs::join_round                 join_strategy(points_per_circle);
            bs::end_round                  end_strategy(points_per_circle);
            bs::point_circle               circle_strategy(points_per_circle);
            bs::side_straight              side_strategy;
    
            bg::buffer(ls, buffered, distance_strategy, side_strategy, join_strategy,
                    end_strategy, circle_strategy);
        }
    }
    

    Which compiles fine for me on my GCC 10, Boost 1.78, Eigen 3.3.4, Rangev3 (0.11.0-44-g81b6d3f1b). Perhaps you were missing an include?