如何从boost::geometry::model::point继承

How to inherit from boost::geometry::model::point?

本文关键字:model point 继承 geometry boost      更新时间:2023-10-16

我想从bg::model::point继承,用自己的功能扩展它。*点*s应存储在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::index

namespace { // 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派生?或者,与其继承,还有更好的方法吗?

谢谢!

Boost.Geometry要求您的点类型适应此处描述的点概念:

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

派生类型myPoint也必须进行调整,因为它与基类型model::pointer<>不同。这样做的原因是该库允许在不需要修改的情况下调整遗留类并将其用作几何体。

为了适应它,你必须使用其中一个注册宏,或者自己专门化所有需要的特征。除了评论中提到的exmaple,请参阅:

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

在第二种方法中,点类型通过手动专业化所有所需特征来适应,这是最灵活的方法。在你的情况下,这看起来像这样:

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

只要把它粘贴在你的点定义之后,你就完成了。