Boost 多边形合并结果在 windows 和 linux 之间不同
Boost polygon union result is differing between windows and linux
我正在尝试通过增强几何体获得所有单个多边形的并集。但奇怪的是,结果似乎在 windows 和 centOS 之间有所不同。
结果在 windows 中是正确的(我期望的那个),但在 linux 中是奇怪的。在 linux 中,结果显示为两个分割多边形。
在Windows我得到
MULTIPOLYGON(((0 -0,0 2996,1490 2996,2980 2996,2980 -0,0 -0)))
但在 centOS 中同样的一组输入,结果为
MULTIPOLYGON(((1490 2996,2980 2996,2980 -0,1490 -0,1490 2996)),((0 2996,1490 2996,1490 -0,0 -0,0 2996)))
这让我感到困惑,因为尝试计算多边形并集的代码是相同的。我不明白为什么 linux 输出会在多边形之间出现一条分割线。这不是联合输出的样子。
谁能指出我在下面的代码中做错了什么?或者我可以尝试查看出了什么问题的任何其他指示。
#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";
}
您可能没有使用相同版本的 boost。
比较:
提升 1.76.0:https://wandbox.org/permlink/UgYfDkwbDZ6I3joZ
polyUnion: MULTIPOLYGON(((0 -0,0 2996,1490 2996,2980 2996,2980 -0,0 -0)))
提升 1.67.0:https://wandbox.org/permlink/SgjKSJjuFUjmwtuT
polyUnion: MULTIPOLYGON(((0 -0,0 2996,1490 2996,2980 2996,2980 -0,0 -0)))
提升 1.63.0:https://wandbox.org/permlink/2XPSR9mO6ILglz4z
polyUnion: MULTIPOLYGON(((1490 0,0 -0,0 2996,1490 2996,2980 2996,2980 -0,1490 0)))
提升 1.60.0:https://wandbox.org/permlink/5Ix5HTjjkoKu24W0
polyUnion: MULTIPOLYGON(((1490 0,0 -0,0 2996,1490 2996,2980 2996,2980 -0,1490 0)))
提升 1.56.0:https://wandbox.org/permlink/nfvzmYDmFRSAUpER
polyUnion: MULTIPOLYGON(((1490 0,0 -0,0 2996,1490 2996,2980 2996,2980 -0,1490 0)))
这是 Boost 的最早版本,甚至有 multi_polygon
header。
我尝试了更多组合(例如 -ffast-math
)只是为了看看我是否可以从问题中得到你的确切输出,但我想我们需要更多信息来重现(版本和标志)。
列表
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/geometries/multi_polygon.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#include <iostream>
#include <vector>
namespace bg = boost::geometry;
namespace bgm = bg::model;
using Point = bgm::d2::point_xy<double>;
using Polygon = bgm::polygon<Point>;
using MultiPoly = bg::model::multi_polygon<Polygon>;
int main()
{
auto check = [](auto name, auto& g) {
if (std::string reason; !bg::is_valid(g, reason)) {
std::cout << name << ": " << reason << "\n";
bg::correct(g);
}
};
Polygon one, two;
bg::read_wkt("POLYGON((0 2996, 1490 2996, 1490 -0, 0 -0, 0 2996))", one);
bg::read_wkt("POLYGON((1490 2996, 2980 2996, 2980 -0, 1490 -0, 1490 2996))", two);
check("one", one);
check("two", two);
MultiPoly polyUnion;
// Create the union of all the polygons of the datasets
for (auto& p : {one, two}) {
MultiPoly tmp;
bg::union_(polyUnion, p, tmp);
polyUnion = tmp;
}
check("polyUnion", polyUnion);
std::cout << "polyUnion: " << bg::wkt(polyUnion) << "\n";
}
标志 BOOST_GEOMETRY_NO_ROBUSTNESS 使提升 API 对 linux 中的同一组输入表现不同。关闭此标志使 windows 和 linux 中的输出相同。
我正在尝试通过增强几何体获得所有单个多边形的并集。但奇怪的是,结果似乎在 windows 和 centOS 之间有所不同。
结果在 windows 中是正确的(我期望的那个),但在 linux 中是奇怪的。在 linux 中,结果显示为两个分割多边形。
在Windows我得到
MULTIPOLYGON(((0 -0,0 2996,1490 2996,2980 2996,2980 -0,0 -0)))
但在 centOS 中同样的一组输入,结果为
MULTIPOLYGON(((1490 2996,2980 2996,2980 -0,1490 -0,1490 2996)),((0 2996,1490 2996,1490 -0,0 -0,0 2996)))
这让我感到困惑,因为尝试计算多边形并集的代码是相同的。我不明白为什么 linux 输出会在多边形之间出现一条分割线。这不是联合输出的样子。
谁能指出我在下面的代码中做错了什么?或者我可以尝试查看出了什么问题的任何其他指示。
#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";
}
您可能没有使用相同版本的 boost。
比较:
提升 1.76.0:https://wandbox.org/permlink/UgYfDkwbDZ6I3joZ
polyUnion: MULTIPOLYGON(((0 -0,0 2996,1490 2996,2980 2996,2980 -0,0 -0)))
提升 1.67.0:https://wandbox.org/permlink/SgjKSJjuFUjmwtuT
polyUnion: MULTIPOLYGON(((0 -0,0 2996,1490 2996,2980 2996,2980 -0,0 -0)))
提升 1.63.0:https://wandbox.org/permlink/2XPSR9mO6ILglz4z
polyUnion: MULTIPOLYGON(((1490 0,0 -0,0 2996,1490 2996,2980 2996,2980 -0,1490 0)))
提升 1.60.0:https://wandbox.org/permlink/5Ix5HTjjkoKu24W0
polyUnion: MULTIPOLYGON(((1490 0,0 -0,0 2996,1490 2996,2980 2996,2980 -0,1490 0)))
提升 1.56.0:https://wandbox.org/permlink/nfvzmYDmFRSAUpER
polyUnion: MULTIPOLYGON(((1490 0,0 -0,0 2996,1490 2996,2980 2996,2980 -0,1490 0)))
这是 Boost 的最早版本,甚至有 multi_polygon
header。
我尝试了更多组合(例如 -ffast-math
)只是为了看看我是否可以从问题中得到你的确切输出,但我想我们需要更多信息来重现(版本和标志)。
列表
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/geometries/multi_polygon.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#include <iostream>
#include <vector>
namespace bg = boost::geometry;
namespace bgm = bg::model;
using Point = bgm::d2::point_xy<double>;
using Polygon = bgm::polygon<Point>;
using MultiPoly = bg::model::multi_polygon<Polygon>;
int main()
{
auto check = [](auto name, auto& g) {
if (std::string reason; !bg::is_valid(g, reason)) {
std::cout << name << ": " << reason << "\n";
bg::correct(g);
}
};
Polygon one, two;
bg::read_wkt("POLYGON((0 2996, 1490 2996, 1490 -0, 0 -0, 0 2996))", one);
bg::read_wkt("POLYGON((1490 2996, 2980 2996, 2980 -0, 1490 -0, 1490 2996))", two);
check("one", one);
check("two", two);
MultiPoly polyUnion;
// Create the union of all the polygons of the datasets
for (auto& p : {one, two}) {
MultiPoly tmp;
bg::union_(polyUnion, p, tmp);
polyUnion = tmp;
}
check("polyUnion", polyUnion);
std::cout << "polyUnion: " << bg::wkt(polyUnion) << "\n";
}
标志 BOOST_GEOMETRY_NO_ROBUSTNESS 使提升 API 对 linux 中的同一组输入表现不同。关闭此标志使 windows 和 linux 中的输出相同。