简体   繁体   English

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

[英]How to inherit from boost::geometry::model::point?

I'd like to inherit from bg::model::point to extend it with own functionality. 我想继承bg :: model :: point来扩展它自己的功能。 The *point*s shall be stored in an rtree . * point * s应存储在rtree中

The following minimal example fails to compile the usage of my derived point (boost 1.54, gcc 4.7.2): 以下最小示例无法编译我的派生点的使用(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;
}

how can i derive from bg::model::point? 我怎样才能从bg :: model :: point派生出来? or, instead of inheriting, is there a better approach? 或者,而不是继承,有更好的方法吗?

thanks! 谢谢!

Boost.Geometry requires that your Point type is adapted to the Point Concept described here: Boost.Geometry要求您的Point类型适应此处描述的Point Concept:

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

Your derived type myPoint must also be adapted because it's a different type than your base type, model::pointer<>. 您的派生类型myPoint也必须进行调整,因为它与您的基类型不同,model :: pointer <>。 The reason for this is that the library allows to adapt legacy classes and use them as Geometries without the need for modification. 这样做的原因是库允许调整遗留类并将它们用作几何图形而无需修改。

To adapt it you must either use one of the registration macros or specialize all required traits by yourself. 要使其适应,您必须使用其中一个注册宏或自己专门化所有必需的特征。 Besides the exmaple mentioned in the comment, see those: 除了评论中提到的例外,请参阅:

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

In the second one the Point type is adapted by manual specialization of all required traits, which is the most flexible approach. 在第二个中,Point类型通过手动专业化所有必需的特征进行调整,这是最灵活的方法。 In your case this would look like this: 在你的情况下,这将是这样的:

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

}}}

Just paste it after your Point definition and you're done. 只需在Point定义后粘贴它就可以了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM