2014-01-29 30 views
4

根据此相关问题(Boost Polygon Serialization)。我正在尝试使用Boost序列化多边形。我现在的问题是,我试图编译使用自定义的X,Y,点的多边形的例子,但是编译器在编译的时候抛出这个错误:Boost多边形序列化:环

error: 'class boost::geometry::model::ring<boost::geometry::model::d2::point_xy<double> >' has no member named 'serialize' 

好像没有定义任何函数序列化戒指。由于一个环从std :: vector扩展而来,并且如相关问题所述,所以没有必要为它的序列化定义一个方法。但编译器抱怨。

这里我有关定义多边形一个完整的例子,它的序列化:

#include <fstream> 

#include <boost/serialization/vector.hpp> 
#include <boost/serialization/nvp.hpp> 
#include <boost/serialization/version.hpp> 
#include <boost/serialization/tracking.hpp> 

#include <boost/geometry/geometry.hpp> 
#include <boost/geometry/geometries/polygon.hpp> 
#include <boost/geometry/geometries/point_xy.hpp> 
#include <boost/geometry/io/wkt/wkt.hpp> 
#include <boost/geometry/multi/geometries/multi_polygon.hpp> 
#include <boost/geometry/geometries/ring.hpp> 

#include <boost/archive/xml_iarchive.hpp> 
#include <boost/archive/xml_oarchive.hpp> 

typedef boost::geometry::model::d2::point_xy<double> point; 
typedef boost::geometry::model::ring<point> ring; 
typedef boost::geometry::model::polygon<point> polygon; 

namespace boost{ 
     namespace serialization{ 

       template<class Archive> 
       inline void serialize(Archive & ar, point &point, const unsigned int file_version) 
       { 
         std::cout << "Point: Serializing point" << std::endl; 
         ar & boost::serialization::make_nvp("x", point.x()); 
         ar & boost::serialization::make_nvp("y", point.y()); 
       } 

       template<class Archive> 
       inline void serialize(Archive & ar, polygon &t, const unsigned int file_version) 
       { 
         std::cout << "Polygon: Serializing outer ring" << std::endl; 
         ar & boost::serialization::make_nvp("outer", t.outer()); 

         std::cout << "Polygon: Serializing inner rings" << std::endl; 
         ar & boost::serialization::make_nvp("inners", t.inners()); 
       } 
     } 
} 

using namespace boost::geometry; 
using namespace boost::archive; 
using namespace std; 

int main() 
{ 
     polygon poly; 
     append(poly, make<point>(0.0, 0.0)); 
     append(poly, make<point>(5.0, 5.0)); 
     append(poly, make<point>(5.0, 0.0)); 
     correct(poly); 

     ofstream ofs("polygon.xml"); 
     xml_oarchive oa(ofs); 
     oa << BOOST_SERIALIZATION_NVP(poly); 
} 

如何得到这个工作任何想法?

编辑:关于多边形系列化全功能代码

#include <fstream> 
#include <vector> 

#include <boost/serialization/vector.hpp> 
#include <boost/serialization/nvp.hpp> 
#include <boost/serialization/version.hpp> 
#include <boost/serialization/tracking.hpp> 
#include <boost/foreach.hpp> 

#include <boost/geometry/geometry.hpp> 
#include <boost/geometry/geometries/polygon.hpp> 
#include <boost/geometry/geometries/point_xy.hpp> 
#include <boost/geometry/geometries/ring.hpp> 

#include <boost/archive/binary_oarchive.hpp> 
#include <boost/archive/binary_iarchive.hpp> 

typedef boost::geometry::model::d2::point_xy<double> point; 
typedef boost::geometry::model::ring<point> ring; 
typedef boost::geometry::model::polygon<point> polygon; 

namespace boost{ 
     namespace serialization{ 

       template<class Archive> 
       inline void serialize(Archive & ar, point &point, const unsigned int file_version) 
       { 
         std::cout << "Point: Serializing point" << std::endl; 
         ar & const_cast<double &>(point.x()); 
         ar & const_cast<double &>(point.y()); 
       } 

       template<class Archive> 
       inline void serialize(Archive & ar, ring &ring, const unsigned int file_version) 
       { 
         std::cout << "Ring: Serializing ring" << std::endl; 
         ar & static_cast<std::vector<point>& >(ring); 
       } 

       template<class Archive> 
       inline void serialize(Archive & ar, polygon &t, const unsigned int file_version) 
       { 
         std::cout << "Polygon: Serializing outer ring" << std::endl; 
         ar & t.outer(); 

         std::cout << "Polygon: Serializing inner rings" << std::endl; 
         ar & t.inners(); 
       } 
     } 
} 

using namespace boost::geometry; 
using namespace boost::archive; 
using namespace std; 

int main() 
{ 
     polygon poly; 
     append(poly, make<point>(0.0, 0.0)); 
     append(poly, make<point>(5.0, 5.0)); 
     append(poly, make<point>(5.0, 0.0)); 
     correct(poly); 

     BOOST_FOREACH(point& p, poly.outer()) 
     { 
       std::cout << "point " << p.x() << "," << p.y() << std::endl; 
     } 

     ofstream ofs("polygon.dat"); 
     binary_oarchive oa(ofs); 
     oa << poly; 
     ofs.close(); 

     polygon polyFromFile; 
     ifstream ifs("polygon.dat"); 
     binary_iarchive ia(ifs); 
     ia >> polyFromFile; 

     BOOST_FOREACH(point& p, polyFromFile.outer()) 
     { 
       std::cout << "point " << p.x() << "," << p.y() << std::endl; 
     } 
     ifs.close(); 
} 

回答

6

即使存在std:vector<T>为serialzation偏特,这并不意味着它会为子类的工作,所以你必须增加一个序列化方法为ring

template<class Archive> 
inline void serialize(Archive & ar, ring &t, const unsigned int file_version) 
{ 
    // Impl 
} 

那么执行什么?由于geometry未构建为序列化,因此无法访问对序列化有用的类型(例如,为容器ring继承选择正确的默认实现),因此您可以以某种方式强制执行此操作。例如,这似乎工作:

template<class Archive> 
inline void serialize(Archive & ar, ring &t, const unsigned int file_version) 
{ 
    std::cout << "Ring: Serializing a ring" << std::endl; 
    serialize(ar, static_cast< std::vector<point>& >(t), file_version); 
} 

您也可以尝试写一些基础类的序列化的呼叫:

template<class Archive> 
inline void serialize(Archive & ar, ring &t, const unsigned int file_version) 
{ 
    std::cout << "Ring: Serializing a ring" << std::endl; 
    ar & boost::serialization::make_nvp("Base", 
       boost::serialization::base_object<std::vector<point> >(t)); 
} 

但同样的,问题是,你应该能够访问继承类从ring。实际上,它中的ring的定义,如base_type,但它对这个类是私有的。如果它是公开的,你可以使用ring::base_type作为序列化的参数(而不是上面的裸露的std::vector<point>)来编写不那么糟糕的代码。

也许知道序列化库的内部,你可以“绑定”序列化机制,这样两个调用就不是必需的,专门为ring类本身专门化了一些局部特化,但是我怀疑这是否便携。

+0

很有洞察力。我喜欢你最后的想法。完全可能值得向Boost Geometry提供建议的那种东西 – sehe

+0

完美的答案!谢谢!我和你的解决方案非常接近,但是我使用“ar&static_cast ...”序列化了这个环,而不是调用序列化方法......它编译的序列化正常,但是没有使用反常序错误的反序列化代码进行编译 –

+0

The与我的方法相同的问题,当调用序列化与静态转换时,序列化的代码似乎工作,但添加反序列化时,它会抛出另一个错误,如'basic_binary_iprimiteve.hpp:88:9:错误:无效转换'const void * 'to'void *' –

0

正如@Diego Sevilla指出的那样,主要障碍在于base_type在ring<...>中声明为private。由于继承事实上是公开的,这有点奇怪。

不过,一个可以稍微用几何模型::详细定义::环

namespace boost { 
namespace serialization{ 
    template<class Archive, //other template params are from model::ring 
      typename Point, 
      bool ClockWise , bool Closed , 
      template<typename, typename> class Container, //= std::vector, 
      template<typename> class Allocator// = std::allocator 
      > 
    void serialize(Archive & ar, 
        geometry::model::ring<Point, ClockWise, 
             Closed, Container, Allocator> & rng, 
        const unsigned int version) 
    { 
     typedef Container<Point, Allocator<Point> > ring_base_type; 
     ring_base_type & contour = rng; 
     ar & BOOST_SERIALIZATION_NVP(contour); 
    } 
} //namespace serialization 
} //namespace boost 

应该正常工作升压::几何模型::几乎所有变种概括他的解决方案::环。

+0

我明白了,但你实际上将定义与'ring'的* exact *实现联系起来。它可能在未来发生变化。 –

+0

同意。至于未来,还有两种选择。首先,可以更改序列号以匹配类“环<...>”。其次,可以使用基于ring的__concept__的更通用的序列化;这意味着必须保存和加载一个通用的随机访问范围点。不过,效率会稍差。 –