将boost::geometry多边形转化为STL对象

8
如何将 boost::geometry 多边形转换为 STL 对象?
我相信这一定很简单,因为文档中没有任何示例。然而,我已经花费了大约四个工作日来尝试完成这一微小的事情。虽然我是 R 的长期程序员,但是这些小数据转换问题让我发狂。
是的,有一个问题的标题与我的类似:从 Boost Geometry 多边形获取点坐标
但是,代码非常复杂(并且发布者改变了它很多次),我无法理解,其他 C++ 初学者也可能无法理解。
这是一个简单的示例,应该适用于其他 boost::geometry 数据类型,因此希望任何人都能理解。
 #include <iostream>

 #include <boost/geometry.hpp>
 #include <boost/geometry/geometries/polygon.hpp>
 #include <boost/geometry/geometries/adapted/boost_tuple.hpp>

 BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)

 //One thing I tried is a function to use with `for_each_point()` so I set that up first.

  template <typename Point>
  void get_coordinates(Point const& p)
  {
  using boost::geometry::get;
  std::cout << get<0>(p) get<1>(p) << std::endl;
  }

  int main()
  {
  typedef boost::tuple<double, double> point;
  typedef boost::geometry::model::polygon<point> polygon;

  polygon poly;
  boost::geometry::read_wkt("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))", poly);

   polygon hull;
   boost::geometry::convex_hull(poly, hull);

 // Now I know I can `dsv()` and print to the screen like this:

  using boost::geometry::dsv;
  std::cout
    << "hull: " << dsv(hull) << std::endl;

  // And/Or I can use my function with for_each_point()



  boost::geometry::for_each_point(hull, get_coordinates<point>);

return 0;
}

如何将这些坐标放入STL容器中?我希望有两个std::vector,一个是x轴坐标,一个是y轴坐标,但是任何容器都可以。

3个回答

6

多边形已经以STL容器格式存在,boost::geometry::polygon将其外部环和内部环存储为std::vector。

考虑到您的评论,您可能需要:

  polygon hull;
  boost::geometry::convex_hull(poly, hull);
  boost::geometry::for_each_point(boost::geometry::exterior_ring(hull), get_coordinates<point>);

如果您更正 get_coordinates 函数为以下形式,那么这个方法就可行了(注意使用 <<):
  template <typename Point>
  void get_coordinates(Point const& p)
  {
      using boost::geometry::get;
      std::cout << get<0>(p) << ", " << get<1>(p) << std::endl;
  }

将您的注释指示器更改为// ;-)


1
我修复了代码中的一些错误,以便更好地与您的答案相匹配。非常感谢您的回复,不幸的是我仍然不理解。我花了很长时间来尝试解密model::polygon的文档,但在一百万年内也不会想到如何获取这些点。让我问几个问题: - politicalEconomist
  1. 你是如何确定多边形对象中的坐标点被称为“外环”的?我看到了Point、PointList、RingList、points、内环,但从来没有看到过“外环”。
  2. 那么你是如何确定外环被存储为std::vector的?
  3. 你是如何知道使用exterior_ring()来访问std::vector的?
- politicalEconomist
即使我现在理解了所有这些,但我仍然不能像使用 std:vector 时那样做所有我通常期望做的事情。例如: double vectSize = boost::geometry::exterior_ring(hull).size(); //返回8但尝试访问元素是不起作用的: double element1 = boost::geometry::exterior_ring(hull)[0];错误:无法将 'boost::tuples::tuple<double,double,...>' 转换为 'double' 在初始化中 - politicalEconomist
1:model::polygon只是Polygon Concept的一个实例。并且exterior_ring通常在Polygon Concept上工作。Boost.Geometry遵循OGC规范,因此这可能会对您的问题提供一些额外的帮助……它不需要是std::vector。它也可以是std::deque等。但是,它应该遵循Boost.Range概念。所有的信息都在文档中(嗯,应该都在文档中)。我是怎么发现的……我写了它。 - Barend Gehrels
4:你应该先熟悉标准库。一个C++程序员应该写int vectSize(或者更好的是std::size_t vectSize)。之后,你可以尝试将double element1设置为向量的元素,这是一个点...一个点不是double类型,一个点包含两个(或更多)double类型。因此,在你的例子中,你应该使用Boost.Tuple接口来获取x或y坐标。所以你也应该熟悉Boost.Tuple。 - Barend Gehrels

0

例如:

boost::geometry::model::polygon<Point> polygon;
polygon.outer().push_back( point );

所以,polygon.outer() 是 std::vector(外部的一个,就像Barend Gehrels所说的那样)。 请参见:boost reference


0

您可以使用迭代器与boost模型一起迭代所有点,并将它们添加到任何类型的容器中。

多边形模型稍微复杂,因为它们有一个外环和潜在的多个内环。

假设您想要“hull”对象(或任何多边形,包括原始“poly”)外环中的所有点,只需迭代它并逐点将其添加到标准向量中即可。

如果您想要x向量和y向量,则使用相同的方法。

::std::vector< point > hullPoints;
::std::vector< double > hullXPoints;
::std::vector< double > hullYPoints;

// the auto keyword makes declaring iterators easy
for ( auto hullIterator = hull.outer().begin;
      hullIterator != hull.outer().end();
      ++hullIterator )
{
     // for a vector of point types, just add the points one by one
     hullPoints.push_back( *hullIterator );

     // for vectors of x and y, extract the x/y from the point
     hullXPoints.push_back( get<0>( *hullIterator ) );
     hullYPoints.push_back( get<1>( *hullIterator ) );
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接