2011-10-11 13 views
8

Tengo una DLL simple haciendo algunos cálculos con los polígonos de Boost Geometry. (En su mayoría, intersecciones y diferencias). Dado que es muy probable que la DLL se llame desde el código C#, y desde Delphi, y quién sabe de dónde más, debería convertir el resultado en matrices que todo pueda manejar.Obtener las coordenadas de los puntos de un polígono de Boost Geometry

ACTUALIZACIÓN: Había simplificado y algo había corregido mi código. El nuevo código se ve completamente diferente, utiliza un enfoque completamente diferente (for_each_point), y de alguna manera todavía no se compila.

Mi nuevo código:

#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; 
     }  
    } 
} 

Los errores de compilación actuales son:

  1. error C2039: 'tipo': no ​​es un miembro de ':: eval_if_c impulsar :: MPL' iterador. HPP 63
  2. C3203 de error: 'tipo': plantilla de clase no especializado no puede ser utilizado como un argumento de plantilla para parámetro de plantilla 'iterador', contaba con un tipo de bienes difference_type.hpp 25
  3. error C2955: 'Impulso :: tipo': uso de la plantilla de clase requiere plantilla de lista de argumentos difference_type.hpp 25
  4. error C2955: 'boost :: iterator_difference': uso de la plantilla de clase requiere plantilla de lista de argumentos difference_type.hpp 26

Los que no parecen tener nada que ver con esta parte del código (mi nombre de archivo es geometry.cpp), pero todo lo demás que usa Boost Geometry está comentado y sigo recibiendo estos errores, así que ...

Here is my bad code that I had previously (edited by sehe)

(Soy nuevo en C++ y Boost, así que tal vez me lo haya perdido me concepto básico al poner código de Internet juntos.) Supongo que no puedo iterar fácilmente a través de un polígono y me perdí la parte no trivial, o que un polígono no puede usarse como un anillo, o las iteraciones son simplemente no de la manera en que pensé que eran, o no tengo idea de qué más puede estar mal. ¿Qué hice mal?

+0

¿Estás obteniendo errores de compilación o estás buscando un error de lógica? ¿Qué es exactamente lo que no funciona para ti? – sbrett

+0

Actualicé mi código. Como no puedo compilar, no sé si estoy haciendo las cosas bien semánticamente, así que estoy buscando cualquier tipo de error que haya cometido. – ytg

+1

La versión de refuerzo que tenía en mi sistema era 1.35, así que actualicé a lo que sea que tengan en el SVN (que pronto será 1,48, creo). Soy capaz de superar los problemas de no tener boost :: geometry y ver exactamente qué tipo de errores está obteniendo, y es complicado, pero no hay tantos. Por lo que puedo decir con solo mirarlo, el método boost :: size definido como parte de lo que creo que es boost_range, no parece saber cómo manejar tu modelo :: polygon . Después de mirar la referencia del rango de impulso, noté que mencionaba funciones requeridas, como range_begin. – sbrett

Respuesta

4

me encontré con un par de cosas que había que fijarse:

  1. Un problema que veo es en sus plantillas. ¡Asegúrate de poner espacios!
  2. intervalo de aumento funciona en contenedores o rangos que contienen pares de inicio, final
  3. Iteradores representa algo así como un puntero a un objeto. Obtener el tamaño del iterador no hará lo que quiera. Necesita usar boost :: tamaño de un contenedor completo, o std :: distance (begin_iterator, end_iterator).

Aquí es una versión que compila:

#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; 
     }  
    } 
} 
+1

Maldita sea, no vi tu respuesta antes de publicar la mía. Disculpas – sbrett

4

Ok, creo que tengo lo que usted está buscando aquí. Todavía no entiendo muy bien por qué estás buscando este rango de lo que supongo que son puntos mayores o iguales a 2, pero descubrí cómo hacerlo compilar cuando usas boost :: size() al menos .

En primer lugar, se dan cuenta de que el primer parámetro de la función

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

es un std :: vector que contiene las instancias de modelo Tipo :: polígono.

Esto significa que cuando deja de hacer referencia a su iterador ... definido como

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

el valor p es un modelo :: polígono.

boost :: model :: polygon NO es en sí mismo compatible con Boost.Range. impulso :: :: modelo polígono es un tipo que contiene funciones 5 miembros ....

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(); 
} 

Esto significa que su * (es decir, un modelo :: polígono) se limita a llamar solamente aquellas funciones.

Lo que parece que quieres hacer es agarrar el anillo exterior o uno de los anillos internos de cada polígono del vector (no estoy seguro de cuál, interno o externo), y ver si el rango de lo que sea en ese anillo es mayor que o igual a 2.

Para hacer esto, debemos hacer más mpl y 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 

Para completar esto y justo arriba y conseguir que "trabajar" Decidí que quería asumir el anillo "externa" de su límite de rango condicional.

Aquí está, para mí, código de compilación, en gcc 4.1.1 con boost 1.48. Dejo si la lógica es correcta para otra persona.

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; 
     } 
    } 
} 
+0

Impresionante trabajo incluso con leer mi mente y descubrir el aspecto del anillo exterior. – ytg

Cuestiones relacionadas