几何,交集

问题描述 投票:0回答:1

我有个问题。我想将四边形与四边形相交。

int main(){
  typedef boost::geometry::model::point_xy<double> TBoostPoint;
  typedef boost::geometry::model::polygon<TBoostPoint> TBoostPoly;
  TBoostPoint point;
  TBoostPoly firstPoly, secondPoly;
  boost::geometry::read_wkt("POLYGON(
                (1.504477611940313, 3.761194029850755), 
                (1.504477611940305, 3.573134328358203),
                (1.316417910447765, 3.573134328358206),
                (1.316417910447769, 3.761194029850752))", firstPoly);
  boost::geometry::read_wkt("POLYGON(
                (1.504477611940313, 3.761194029850755), 
                (1.504477611940305, 3.573134328358203),
                (1.316417910447765, 3.573134328358206),
                (1.316417910447751, 3.761194029850769))", secondPoly);
 std::vector<TBoostPoly> outPoly;
 boost::geometry::intersection(firstPoly,secondPoly,outPoly);
}

outPoly - 是空的,但事实并非如此。

c++ boost intersection boost-geometry
1个回答
3
投票

有两个主要问题。

输出未定义,因为输入无效。

  1. 输入WKT指定了许多无效的内环(由单个点组成),而不是你预期的,一个5点的外环(不包括关闭点)。修理它: bg::read_wkt("POLYGON(( 1.504477611940313 3.761194029850755, 1.504477611940305 3.573134328358203, 1.316417910447765 3.573134328358206, 1.316417910447769 3.761194029850752))", first); bg::read_wkt("POLYGON(( 1.504477611940313 3.761194029850755, 1.504477611940305 3.573134328358203, 1.316417910447765 3.573134328358206, 1.316417910447751 3.761194029850769))", second);
  2. Boost Geometry假定您始终不会对记录的前提条件产生错误。如果您阅读多边形概念页面和intersection的前提条件,您将看到完整列表¹。 如果不这样做,您就不会遇到任何友好错误,只会出现无声失败,腐败或错误的答案。是啊。那很糟。 更糟糕的是,在Boost 1_57(IIRC)之前,BGeo甚至没有is_valid工具来测试大部分需求。好消息是,如果你升级到这个版本或以后你的生活会更简单。

在这种情况下,您将了解到多边形未正确关闭:

Live On Coliru

#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/io/io.hpp>
#include <boost/geometry/algorithms/intersection.hpp>
#include <boost/geometry/algorithms/correct.hpp>
#include <boost/geometry/algorithms/is_valid.hpp>

namespace bg = boost::geometry;

int main(){
    typedef bg::model::d2::point_xy<double> TPoint;
    typedef bg::model::polygon<TPoint>      TPoly;
    TPoly first, second;

    bg::read_wkt("POLYGON(( 1.504477611940313 3.761194029850755, 1.504477611940305 3.573134328358203, 1.316417910447765 3.573134328358206, 1.316417910447769 3.761194029850752))", first);
    bg::read_wkt("POLYGON(( 1.504477611940313 3.761194029850755, 1.504477611940305 3.573134328358203, 1.316417910447765 3.573134328358206, 1.316417910447751 3.761194029850769))", second); 

    std::string reason;
    // polys not closed!
    if (!bg::is_valid(first, reason))  std::cout << "First polygon not valid: "  << reason << "\n";
    if (!bg::is_valid(second, reason)) std::cout << "Second polygon not valid: " << reason << "\n";

    bg::correct(first);
    bg::correct(second);

    // no more output!
    if (!bg::is_valid(first, reason))  std::cout << "First polygon not valid: "  << reason << "\n";
    if (!bg::is_valid(second, reason)) std::cout << "Second polygon not valid: " << reason << "\n";

    std::vector<TPoly> out;
    bg::intersection(first, second, out);

    for (auto& g : out)
        std::cout << "\nresult: " << bg::wkt(g) << "\n";
}

打印:

First polygon not valid: Geometry is defined as closed but is open
Second polygon not valid: Geometry is defined as closed but is open

哎呀。地理位置没有关闭! correct(poly)通过自动驾驶为我们解决了这个问题:

result: POLYGON((1.50448 3.57313,1.31642 3.57313,1.31642 3.76119,1.50448 3.76119,1.50448 3.57313))

¹外圈必须是逆时针,内部cw,多边形必须关闭......这样的东西。

© www.soinside.com 2019 - 2024. All rights reserved.