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.