Как наследовать от boost :: geometry :: model :: point?

Я хотел бы унаследовать от BG :: Модель :: Точка расширить его с собственной функциональностью. * Точки * должны храниться в rtree.

В следующем минимальном примере не удается скомпилировать использование моей производной точки (boost 1.54, gcc 4.7.2):

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <iostream>
#include <boost/shared_ptr.hpp>

namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;

namespace boost { namespace geometry { namespace index {

// apparently necessary:
template <typename Box>
struct indexable< boost::shared_ptr<Box> >
{
typedef boost::shared_ptr<Box> V;

typedef Box const& result_type;
result_type operator()(V const& v) const { return *v; }
};

}}} // namespace boost::geometry::indexnamespace { // anonymous namespace

// myPoint
template<typename CoordinateType, std::size_t DimensionCount, typename CoordinateSystem>
class myPoint : public bg::model::point<CoordinateType, DimensionCount, CoordinateSystem>{
public:
void sayHello(void);
};

template<typename CoordinateType, std::size_t DimensionCount, typename CoordinateSystem>
void myPoint< CoordinateType, DimensionCount, CoordinateSystem >::sayHello() {
std::cout<<"Hello!"<<std::endl;
}

} // end anonymous namespace

int main(void)
{
typedef bg::model::point<float, 2, bg::cs::cartesian> point; // boost point version
typedef myPoint<float, 2, bg::cs::cartesian> mypoint; // custom point version

// create the rtree using default constructor
bgi::rtree< boost::shared_ptr<point>, bgi::rstar<16, 4> > rtree; // that works
bgi::rtree< boost::shared_ptr<mypoint>, bgi::rstar<16, 4> > myrtree; // that doesn't works

return 0;
}

как я могу получить из bg :: model :: point? или вместо наследования есть лучший подход?

Спасибо!

4

Решение

Boost.Geometry требует, чтобы ваш тип точек был адаптирован к описанной здесь концепции точек:

http://www.boost.org/doc/libs/1_54_0/libs/geometry/doc/html/geometry/reference/concepts/concept_point.html

Ваш производный тип myPoint также должен быть адаптирован, потому что он отличается от вашего базового типа, модель :: указатель<>. Причиной этого является то, что библиотека позволяет адаптировать унаследованные классы и использовать их в качестве геометрии без необходимости модификации.

Чтобы адаптировать его, вы должны либо использовать один из макросов регистрации, либо специализировать все необходимые черты самостоятельно. Помимо примера, упомянутого в комментарии, см. Те:

http://www.boost.org/doc/libs/1_54_0/libs/geometry/doc/html/geometry/examples.html

Во втором тип Point адаптируется путем ручной специализации всех требуемых черт, что является наиболее гибким подходом. В вашем случае это будет выглядеть так:

namespace boost { namespace geometry { namespace traits {

template <typename C, std::size_t D, typename S>
struct tag< myPoint<C, D, S> >
{
typedef point_tag type;
};
template <typename C, std::size_t D, typename S>
struct coordinate_type< myPoint<C, D, S> >
{
typedef C type;
};
template <typename C, std::size_t D, typename S>
struct coordinate_system< myPoint<C, D, S> >
{
typedef S type;
};
template <typename C, std::size_t D, typename S>
struct dimension< myPoint<C, D, S> >
{
static const std::size_t value = D;
};
template <typename C, std::size_t D, typename S, std::size_t I>
struct access<myPoint<C, D, S>, I>
{
static inline C get(myPoint<C, D, S> const& p)
{
return p.template get<I>();
}

static inline void set(myPoint<C, D, S> & p, C const& v)
{
p.template set<I>(v);
}
};

}}}

Просто вставьте его после определения точки, и все готово.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]