I am trying to get a union of all the individual polygons via boost geometry. But oddly the results seem to vary between windows and centOS.
The result is coming out right one (the one i expect) in windows BUT in linux its odd. In linux it shows result as two split polygons.
In Windows i get
MULTIPOLYGON(((0 -0,0 2996,1490 2996,2980 2996,2980 -0,0 -0)))
But in centOS same set of inputs, give result as
MULTIPOLYGON(((1490 2996,2980 2996,2980 -0,1490 -0,1490 2996)),((0 2996,1490 2996,1490 -0,0 -0,0 2996)))
Its baffling for me as the code trying to compute polygons union is same. I don’t understand why the linux output is coming out with a split line in between polygons. That’s not how a union output should look like.
Can anyone point out what is that i am doing wrong in below code? Or any other pointers which i could try to see whats going wrong.
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/multi_polygon.hpp>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <vector>
#include <boost/geometry.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
namespace boost {
namespace geometry {
typedef model::d2::point_xy<double> Point;
typedef model::polygon<Point> Polygon;
typedef model::segment<Point> Line;
};
};
int main()
{
using multi_polygon = boost::geometry::model::multi_polygon<boost::geometry::Polygon>;
boost::geometry::Polygon one, two,green;
boost::geometry::read_wkt("POLYGON((0 2996, 1490 2996, 1490 -0, 0 -0, 0 2996))", one);
boost::geometry::read_wkt("POLYGON((1490 2996, 2980 2996, 2980 -0, 1490 -0, 1490 2996))", two);
multi_polygon polyUnion;
std::vector<boost::geometry::Polygon> vectorOfPolygons;
vectorOfPolygons.emplace_back(one);
vectorOfPolygons.emplace_back(two);
// Create the union of all the polygons of the datasets
for (const boost::geometry::Polygon& p : vectorOfPolygons) {
multi_polygon tmp;
boost::geometry::union_(polyUnion, p, tmp);
polyUnion = tmp;
boost::geometry::clear(tmp);
}
std::string str;
bool valid = boost::geometry::is_valid(polyUnion, str);
if (!valid)
{
boost::geometry::correct(polyUnion);
}
std::cout << "Result of union" << boost::geometry::wkt(polyUnion) << "n";
}
2
Answers
The flag BOOST_GEOMETRY_NO_ROBUSTNESS made the boost API behave differently for same set of inputs in linux. Turning OFF this flag made the output to become same in windows and linux.
You’re likely not using the same version of boost.
Compare:
boost 1.76.0: https://wandbox.org/permlink/UgYfDkwbDZ6I3joZ
boost 1.67.0: https://wandbox.org/permlink/SgjKSJjuFUjmwtuT
boost 1.63.0: https://wandbox.org/permlink/2XPSR9mO6ILglz4z
boost 1.60.0: https://wandbox.org/permlink/5Ix5HTjjkoKu24W0
boost 1.56.0: https://wandbox.org/permlink/nfvzmYDmFRSAUpER
That’s the earliest version of Boost that even has the
multi_polygon
header.I tried some more combinations (e.g. with
-ffast-math
) just to see whether I could get your exact output from the question, but I guess we need more information to reproduce that (versions and flags).Listing