10

Boost Geometry ポリゴンを使用していくつかの計算を行う単純な DLL があります。(主に共通点と相違点です。) 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;
        }       
    }
}

現在のコンパイル エラーは次のとおりです。

  1. エラー C2039: 'type': 'boost::mpl::eval_if_c' iterator.hpp 63 のメンバーではありません
  2. error C3203: 'type': 特殊化されていないクラス テンプレートは、テンプレート パラメーター '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 を初めて使用するので、インターネットからコードをまとめる際にいくつかの基本的な概念を見逃している可能性があります。) 簡単に多角形を反復処理できず、重要な部分を見逃していたと思います。ポリゴンをリングとして使用できないか、反復が思ったとおりでないか、他に何が間違っているのかわかりません。私は何を間違えましたか?

4

2 に答える 2

5

わかりました、私はあなたが探しているものをここに持っていると思います。2以上のポイントであると想定するこの範囲を探している理由はまだよくわかりませんが、少なくともboost::size()を使用するときにコンパイルする方法を見つけました。

まず、関数の最初のパラメーターが

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

model::polygon 型のインスタンスを含む std::vector です。

これは、イテレータを逆参照すると ...次のように定義されることを意味します

std::vector<model::polygon<spherical_point> >::iterator it

右辺値は 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();
} 

これは、*it (つまり、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 

これを完了して「機能する」ようにするために、範囲制限条件付きの「外側」リングが必要であると仮定することにしました。

これは、ブースト1.48を使用したgcc 4.1.1でのコードのコンパイルです。ロジックが正しいかどうかは他の人に任せます。

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;
      }
    }
}
于 2011-10-13T00:24:17.717 に答える
4

修正が必要なことがいくつか見つかりました。

  1. 私が目にする 1 つの問題は、テンプレートにあります。必ずスペースを入れてください!
  2. ブースト範囲は、開始、終了のペアを保持するコンテナーまたは範囲で機能します
  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;
        }       
    }
}
于 2011-10-12T23:52:45.580 に答える