Boost 多边形联合结果在 windows 和 linux 之间是不同的

Posted

技术标签:

【中文标题】Boost 多边形联合结果在 windows 和 linux 之间是不同的【英文标题】:Boost polygon union result is differing between windows and linux 【发布时间】:2021-11-13 15:54:29 【问题描述】:

我正在尝试通过增强几何来合并所有单个多边形。但奇怪的是,结果似乎在 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】:

标志 BOOST_GEOMETRY_NO_ROBUSTNESS 使 boost API 对 linux 中的同一组输入表现不同。关闭此标志使输出在 windows 和 linux 中变得相同。

【讨论】:

【参考方案2】:

您可能没有使用相同版本的 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 标头。

我尝试了更多组合(例如,使用 -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";

【讨论】:

谢谢。所以你的意思是你看不到我看到的答案,即 o/p 显示两个多边形,中间用一条线隔开?确定我在 CentOS 中使用的 boost 版本的最简单方法是什么?是否可以通过一些标题等查看? 当然。我不会给你确切的建议,因为我们缺乏关于你如何配置的信息,但boost/version.hpp 将是要寻找的东西(你也可以只包含并输出其中定义的数字) 增强版好像 1.68.0 。我完全不知道为什么当我的代码作为更大项目的一部分运行时会得到这个奇怪的输出。使用这个单独的测试程序,它可以正常工作,但作为更大项目的一部分,它给出了我在原始问题中发布的输出(似乎联合只是收集所有单独的输入)。打败我 也许你可以减少周围的代码,直到问题消失,隔离原因 调试显示我的错误代码只是将单个多边形添加到 CentOS 中的联合多边形中。相同的代码在 Windows 中完美运行。我真的很困惑,为什么在 CentOS 上它只是在联合中添加单个多边形而不是像 windows 一样。

以上是关于Boost 多边形联合结果在 windows 和 linux 之间是不同的的主要内容,如果未能解决你的问题,请参考以下文章

Boost Geometry:联合多个多边形 C++

在 boost 几何中创建实心多边形

提升几何相交会产生奇怪的结果

合并许多凸多边形的快速算法或库

boost几何中的环和多边形有什么区别?

增强几何返回相交和相交的不一致结果