【问题标题】:boost::geometry::read_wkt alternative?boost::geometry::read_wkt 替代方案?
【发布时间】:2014-11-07 15:18:30
【问题描述】:

我正在尝试检查一个点是否在多边形内。为此,我想使用 boost 库。我的问题是如何修改 boost 中的示例,而不是通过 read_wkt 读取点,而是从 std 向量中读取它们。

这是来自 boost 的示例代码:

#include <iostream>
#include <list>

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>


int main()
{
    typedef boost::geometry::model::d2::point_xy<double> point_type;
    typedef boost::geometry::model::polygon<point_type> polygon_type;

    polygon_type poly;
    boost::geometry::read_wkt(
        "POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 3,5.3 2.6,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3)"
            "(4.0 2.0, 4.2 1.4, 4.8 1.9, 4.4 2.2, 4.0 2.0))", poly);

    point_type p(4, 1);

    std::cout << "within: " << (boost::geometry::within(p, poly) ? "yes" : "no") << std::endl;

    return 0;
}

这是我的 vecPoints:

struct PNTS{
int x;
int y;
}
std::vector<PNTS> vecPoints;

请注意:我的问题与多边形算法中的点有关。

【问题讨论】:

  • 为什么不遍历你的向量并构建 WKT 字符串?这行得通吗?
  • 不工作,我猜...
  • @AnasAlkhatib 将此方法添加为我的第二个答案

标签: c++ boost boost-geometry


【解决方案1】:

如果您想在 boost 中的多边形内添加矢量成员:

using boost::geometry::append;
using boost::geometry::make;
using boost::geometry::correct;
std::vector<PNTS>::iterator iter;
for(iter = vecPoints.begin(); iter != vecPoints.end(); iter++)
{
  PNTS ver = *iter;
  append( poly, make<boost2dPoint>(ver.x, ver.y) );
}
// you have to close polygon by inserting first element as the last again
PNTS last = vecPoints[vecPoints.size()-1];
append( poly, make<boost2dPoint>(last.x, last.y) );
// you can also correct the polygon orientation
correct(poly);

【讨论】:

  • 怎么能正常工作,他把最后一点追加了两次,最后..
【解决方案2】:

我不太了解几何概念。但是,这看起来应该很接近,或者至少会给您一些关于如何做事的灵感。

更新添加序列化 WKT,所以我们可以确认多边形是相同的。

Live On Coliru

#include <iostream>
#include <list>

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/io/io.hpp>

int main()
{
    typedef boost::geometry::model::d2::point_xy<double> point_type;
    typedef boost::geometry::model::polygon<point_type> polygon_type;

    polygon_type poly;
    poly.outer().assign({
        point_type {     2,   1.3   },
        point_type {   2.4,   1.7   },
        point_type {   2.8,   1.8   },
        point_type {   3.4,   1.2   },
        point_type {   3.7,   1.6   },
        point_type {   3.4,     2   },
        point_type {   4.1,     3   },
        point_type {   5.3,   2.6   },
        point_type {   5.4,   1.2   },
        point_type {   4.9,   0.8   },
        point_type {   2.9,   0.7   },
        point_type {     2,   1.3   },
    });

    poly.inners().emplace_back();
    poly.inners().back().assign({
        {   4.0,   2.0   },
        {   4.2,   1.4   },
        {   4.8,   1.9   },
        {   4.4,   2.2   },
        {   4.0,   2.0   },
    });

    point_type p(4, 1);

    std::cout << "within: " << (boost::geometry::within(p, poly) ? "yes" : "no") << std::endl;

    std::cout << boost::geometry::wkt(poly) << "\n";
}

打印

within: yes
POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 3,5.3 2.6,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3),(4 2,4.2 1.4,4.8 1.9,4.4 2.2,4 2))

【讨论】:

  • 谢谢,我在使用 boost 1.56 时遇到了一个错误:错误:没有匹配函数调用 'boost::geometry::model::ring<:geometry::model:: d2::point_xy>, true, true, std::vector, std::allocator>::assign()'
  • 哦,好吧。显然你的编译器有点 c++11 的挑战。为方便起见,我将按迭代器范围从临时向量初始化:paste.ubuntu.com/8901103(Coliru 暂时关闭)
【解决方案3】:

如果像评论者所说的那样,您认为手动从向量创建 WKT 更容易,这是一种方法,只需大约 2 行代码,无需使用 Boost Geometry 中的任何东西:

using namespace boost::spirit::karma;
std::cout << format_delimited("POLYGON(" << *('(' << auto_%',' << ')') << ")\n", ' ', rings);

完整演示Live On Coliru

#include <iostream>
#include <boost/fusion/adapted/boost_tuple.hpp>
#include <boost/spirit/include/karma.hpp>

int main()
{
    using Ring = std::vector<boost::tuple<double,double>>;

    std::vector<Ring> rings = {
        {   {   2, 1.3 }, { 2.4, 1.7 }, { 2.8, 1.8 }, { 3.4, 1.2 },
            { 3.7, 1.6 }, { 3.4,   2 }, { 4.1,   3 }, { 5.3, 2.6 },
            { 5.4, 1.2 }, { 4.9, 0.8 }, { 2.9, 0.7 }, {   2, 1.3 },
        },
        {   { 4.0, 2.0 }, { 4.2, 1.4 }, { 4.8, 1.9 }, { 4.4, 2.2 }, { 4.0, 2.0   },
        }
    };

    using namespace boost::spirit::karma;
    std::cout << format_delimited("POLYGON(" << *('(' << auto_%',' << ')') << ")\n", ' ', rings);
}

打印:

POLYGON( ( 2.0 1.3 , 2.4 1.7 , 2.8 1.8 , 3.4 1.2 , 3.7 1.6 , 3.4 2.0 , 4.1 3.0 , 5.3 2.6 , 5.4 1.2 , 4.9 0.8 , 2.9 0.7 , 2.0 1.3 ) ( 4.0 2.0 , 4.2 1.4 , 4.8 1.9 , 4.4 2.2 , 4.0 2.0 ) )

【讨论】:

    猜你喜欢
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 2012-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多