Dear all,

I have used successfully the buffering algorithm to offset a shapefile of 2D polygons. However, there  are 4 polygons (amongst nearly 4000) in my SHP does are not successfully processed. They do not have topology or orientation errors.

I use GDAL 1.9 to read the SHP, boost 1.56 precompiled binaries from sourceforge on a 64bit windows 7. If someone is willing to have a look at the problem, I can share the files and the code I use. Here is a quick overview:


    typedef double coordinate_type;
    typedef boost::geometry::model::d2::point_xy<coordinate_type> point_xy_type;
    typedef boost::geometry::model::polygon<point_xy_type> polygon_type;
    boost::geometry::strategy::buffer::end_flat end_strategy;
    boost::geometry::strategy::buffer::point_square point_strategy;
    boost::geometry::strategy::buffer::side_straight side_strategy;

    boost::geometry::strategy::buffer::distance_symmetric<coordinate_type> distance_strategy(buffer_distance);
    boost::geometry::strategy::buffer::join_miter join_strategy(buffer_distance);

                polygon_type p;
                boost::geometry::model::multi_polygon<polygon_type> result;

                // Build a polygon_type from OGRPolygon
                OGRLinearRing* exteriorRing = polygon->getExteriorRing();
                for(int i=0;i<exteriorRing->getNumPoints();++i)
                {
                    OGRPoint pt;
                    exteriorRing->getPoint(i,&pt);

                    p.outer().push_back( point_xy_type(pt.getX(), pt.getY()) );
                }
                for(int i=0;i<polygon->getNumInteriorRings();++i)
                {
                    OGRLinearRing* interiorRing = polygon->getInteriorRing(i);
                    polygon_type::ring_type ring;

                    for(int j=0;j<interiorRing->getNumPoints();++j)
                    {
                        OGRPoint pt;
                        interiorRing->getPoint(j,&pt);

                        ring.push_back( point_xy_type(pt.getX(), pt.getY()) );
                    }
                    p.inners().push_back(ring);
                }

                boost::geometry::buffer(p, result, distance_strategy, side_strategy, join_strategy, end_strategy, point_strategy);

                if(result.size() == 0)
                {
                    int indexID = feature->GetFieldIndex("ID");
                    cout << "No result build for polygon with ID " << feature->GetFieldAsString(indexID) << endl;
                }
                else
                {
                    typedef boost::geometry::strategy::distance::pythagoras<coordinate_type> pythagoras_distance_strategy;
                    typedef boost::geometry::strategy::distance::projected_point<coordinate_type, pythagoras_distance_strategy> projected_point_strategy;
                    boost::geometry::strategy::simplify::douglas_peucker<point_xy_type, projected_point_strategy> dp;

                    OGRPolygon poly;

                    for(size_t i=0;i<result.size();++i)
                    {
                        polygon_type result_i = result[i];
                        polygon_type result_i_simplified;

                        boost::geometry::simplify(result_i, result_i_simplified, 0.1, dp);

                        {
                            OGRLinearRing ring;
                            for(size_t j=0;j<result_i_simplified.outer().size();++j)
                                ring.addPoint( result_i_simplified.outer()[j].x(), result_i_simplified.outer()[j].y() );
                            poly.addRing(&ring);
                        }

                        {
                            OGRLinearRing ring;
                            for(size_t j=0;j<result_i_simplified.inners().size();++j)
                            {
                                for(size_t k=0;k<result_i_simplified.inners()[j].size();++k)
                                {
                                    ring.addPoint( result_i_simplified.inners()[j][k].x(), result_i_simplified.inners()[j][k].y() );
                                }
                                poly.addRing(&ring);
                            }
                        }
                    }

Note that I use a simplification algorithm after buffering to remove colinear points.

Hope you could help.

Best regards,

Olivier