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

I would like to inherit from bg :: model :: point in order to extend it with my own functionality. * Point * s is stored in rtree .

The following minimal example cannot compile using my derived point (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 get from bg :: model :: point? or is there a better approach instead of inheritance?

thanks!

+4
source share
1 answer

Boost.Geometry requires your point type to be adapted to the point described here:

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 is different from your base type, model :: pointer <>. The reason for this is that the library allows you to adapt obsolete classes and use them as geometry without modification.

To adapt it, you must either use one of the registration macros, or independently determine all the necessary features. Besides the comment above, see Those:

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

In the second, the Point type is adapted by manual specialization of all the necessary attributes, which is the most flexible approach. In your case, it will 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 insert it after defining the point and finish.

+3
source

Source: https://habr.com/ru/post/1495339/


All Articles