从Boost Geometry多边形获取点的坐标

ytg*_*ytg 10 c++ boost boost-geometry

我有一个简单的DLL用Boost Geometry多边形做一些计算.(主要是交叉点和差异.)因为DLL很可能是从C#代码调用的,而且是从Delphi调用的,我应该将结果转换为所有可以处理的数组.

更新: 我已经简化并稍微纠正了我的代码.新代码看起来完全不同,使用完全不同的方法(for_each_point),并且仍然不能编译.

我的新代码:

#include <vector>
#include <boost/range.hpp>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/polygon.hpp>

using namespace boost::geometry;

typedef boost::geometry::model::point
    <
        double, 2, boost::geometry::cs::spherical_equatorial<boost::geometry::degree>
    > spherical_point;
class PointAggregator {
private :
    double *x, *y;
    int count;

public :
    PointAggregator(int size) {
        x = (double*) malloc(sizeof(double) * size);
        y = (double*) malloc(sizeof(double) * size);
        count = 0;
    }

    ~PointAggregator() {
        free(x);
        free(y);
    }

    inline void operator()(spherical_point& p) {
        x[count] = get<0>(p);
        y[count] = get<1>(p);
        count++;
    }

    void GetResult(double *resultX, double *resultY) {
        resultX = x;
        resultY = y;
    }
};

void VectorToArray(std::vector<model::polygon<spherical_point>> resultVector, double x[], double y[], int *count) {
    int i = 0;      
    for (std::vector<model::polygon<spherical_point>>::iterator it = resultVector.begin(); it != resultVector.end(); ++it) {
        if (boost::size(*it) >= 2) {
            *count = boost::size(*it);
            PointAggregator* pa = new PointAggregator(*count);
            boost::geometry::for_each_point(*it, *pa);
            pa->GetResult(x, y);
            delete(pa);
            break;
        }       
    }
}
Run Code Online (Sandbox Code Playgroud)

目前的编译错误是:

  1. 错误C2039:'type':不是'boost :: mpl :: eval_if_c'的成员iterator.hpp 63
  2. 错误C3203:'type':unspecialized类模板不能用作模板参数'Iterator'的模板参数,期望一个真正的类型difference_type.hpp 25
  3. 错误C2955:'boost :: type':使用类模板需要模板参数列表difference_type.hpp 25
  4. 错误C2955:'boost :: iterator_difference':使用类模板需要模板参数列表difference_type.hpp 26

哪些看起来与这部分代码(我的文件名是geometry.cpp)有什么关系,但是使用Boost Geometry的其他所有东西都被注释掉了,我仍然会得到这些错误,所以...

这是我之前的错误代码(由sehe编辑)

(我是C++和Boost的新手所以我可能在将代码从互联网上放到一起时错过了一些基本概念.)我假设我不能轻易地遍历多边形,而我错过了非平凡的部分,或者那个多边形不能用作环,或者迭代不是我认为的那样,或者我不知道还有什么可能是错的.我做错了什么?

sbr*_*ett 5

好的,我想我已经找到了你想要的东西.我仍然不太明白你为什么要寻找这个我认为大于或等于2的点的范围,但我想办法在至少使用boost :: size()时如何编译它.

首先,实现函数的第一个参数

void VectorToArray(std::vector<model::polygon<spherical_point> > resultVector, double x[], double y[], int *count)
{
...
}
Run Code Online (Sandbox Code Playgroud)

是一个std :: vector,包含model :: polygon类型的实例.

这意味着当您取消引用迭代器时...定义为

std::vector<model::polygon<spherical_point> >::iterator it
Run Code Online (Sandbox Code Playgroud)

rvalue是一个model :: polygon.

boost :: model :: polygon不在Boost.Range中.boost :: model :: polygon是一个包含5个成员函数的类型....

inline ring_type const& outer() const { return m_outer; }
inline inner_container_type const& inners() const { return m_inners; }
inline ring_type& outer() { return m_outer; }
inline inner_container_type & inners() { return m_inners; }
inline void clear()
{
    m_outer.clear();
    m_inners.clear();
} 
Run Code Online (Sandbox Code Playgroud)

这意味着你的*它(即一个model :: polygon)仅限于调用那些函数.

你想要做的是抓住矢量中每个多边形的外环或一个内环(不确定哪个,内部或外部),并查看该环中任何内容的范围是否大于或等于2.

要做到这一点,我们必须做更多的mpl和typedef.

typedef boost::geometry::model::point<double, 2, boost::geometry::cs::spherical_equatorial<boost::geometry::degree> > spherical_point; // your definition of a spherical_point
typedef boost::geometry::model::polygon<spherical_point> polygon; //consolidation of template args for a polygon
typedef boost::geometry::ring_type<polygon>::type ring_type; // define a ring_type that can handle your spherical_point by way of the polygon typedef.
typedef boost::geometry::interior_type<polygon>::type int_type; //define a interior_type  that can handle your spherical_point 
Run Code Online (Sandbox Code Playgroud)

为了完成这个并且让它"正常工作",我决定假设你想要有条件的范围限制的"外部"环.

对我来说,编译代码,在gcc 4.1.1上使用boost 1.48.我留下逻辑是否正确到其他人.

using namespace boost::geometry;
typedef boost::geometry::model::point<double, 2, boost::geometry::cs::spherical_equatorial<boost::geometry::degree> > spherical_point;
typedef boost::geometry::model::polygon<spherical_point> polygon;
typedef boost::geometry::ring_type<polygon>::type ring_type;
typedef boost::geometry::interior_type<polygon>::type int_type;

class PointAggregator 
{
private :
    double *x, *y;
    int count;

public :
    PointAggregator(int size) 
    {
        x = (double*) malloc(sizeof(double) * size);
        y = (double*) malloc(sizeof(double) * size);
        count = 0;
    }

    ~PointAggregator() 
    {
        free(x);
        free(y);
    }

    inline void operator()(spherical_point& p) 
    {
        x[count] = get<0>(p);
        y[count] = get<1>(p);
        count++;
    }

    void GetResult(double *resultX, double *resultY) 
    {
        resultX = x;
        resultY = y;
    }
};

void VectorToArray(std::vector<model::polygon<spherical_point> > resultVector, double x[], double y[], int *count) 
{
    for (std::vector<model::polygon<spherical_point> >::iterator it = resultVector.begin(); it != resultVector.end(); ++it) 
    {
      model::polygon<spherical_point> tmpPoly;
      tmpPoly = (*it);

      boost::geometry::ring_type<polygon>::type somering = tmpPoly.outer(); //typed it all out again instead of using ring_type since the complier was complaining and i didn't wanna get into it.
      int ringsize = boost::size(somering);
      if(ringsize >= 2)
      {

          *count = ringsize;
          PointAggregator* pa = new PointAggregator(*count);
          boost::geometry::for_each_point(*it, *pa);
          pa->GetResult(x, y);
          delete(pa);
          break;
      }
    }
}
Run Code Online (Sandbox Code Playgroud)


And*_*ndt 4

我发现有一些问题需要修复:

  1. 我看到的一个问题是在你的模板中。一定要加空格!
  2. boost range 适用于保存开始、结束对的容器或范围
  3. 迭代器代表类似于指向对象的指针。获取迭代器的大小不会达到您想要的效果。您需要使用整个容器的 boost::size 或 std::distance(begin_iterator,end_iterator)。

这是一个可以编译的版本:

#include <vector>
#include <boost/range.hpp>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/polygon.hpp>

using namespace boost::geometry;

typedef boost::geometry::model::point
    <
        double, 2, boost::geometry::cs::spherical_equatorial<boost::geometry::degree>
    > spherical_point;
class PointAggregator {
private :
    double *x, *y;
    int count;

public :
    PointAggregator(int size) {
        x = (double*) malloc(sizeof(double) * size);
        y = (double*) malloc(sizeof(double) * size);
        count = 0;
    }

    ~PointAggregator() {
        free(x);
        free(y);
    }

    inline void operator()(spherical_point& p) {
        x[count] = get<0>(p);
        y[count] = get<1>(p);
        count++;
    }

    void GetResult(double *resultX, double *resultY) {
        resultX = x;
        resultY = y;
    }
};

// added spaces to the close brackets >> becomes > >
void VectorToArray(std::vector<model::polygon<spherical_point> > resultVector, double x[], double y[], int *count) {
    for (std::vector<model::polygon<spherical_point> >::iterator it = resultVector.begin(); it != resultVector.end(); ++it) {
        if (boost::size(resultVector) >= 2) {
            // getting the size of the whole container
            *count = boost::size(resultVector);
            PointAggregator* pa = new PointAggregator(*count);
            boost::geometry::for_each_point(*it, *pa);
            pa->GetResult(x, y);
            delete(pa);
            break;
        }       
    }
}
Run Code Online (Sandbox Code Playgroud)