Question

I am using boost geometry in my project, and I need to serialize polygons. I have been using boost serialization without problems for many boost data types, but boost geometry seems that currently does not support serialization, as I cannot find any header inside serialization folder.

Is there any well known method to achieve this?

Thanks.

EDIT: Binary Serialization Example in: Boost Polygon Serialization: Ring

Was it helpful?

Solution

I agree, it is weird that Boost.Geometry does not support Boost.Serialization. Probably it is hard to support all possible combinations of template parameters, or maybe they did not bother as WKT is already provided.

At least in the case of "default" container types it is trivial to add such functionality. The code below implements it and is fully functional.

Below I assume you use a custom class (QPoint from Qt) as your point class. Code for other point types will be almost identical to mine.

First, you add a serialization for the Point class:

#include <QPoint>

#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/register/point.hpp>

BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(QPoint, int, cs::cartesian, x, y, setX, setY);
typedef QPoint MyPoint;


namespace  boost {
namespace serialization {

template<class Archive>
void serialize(Archive & ar, MyPoint& pt, const unsigned int version) {
    ar &  boost::serialization::make_nvp("x", pt.rx() );
    ar &  boost::serialization::make_nvp("y", pt.ry() );
}
} //namespace serialization
} //namespace boost

Next you add serialization for Ring and Polygon. Here I use the fact that Ring and Polygon are essentially std::vector(s) of points and rings respectively and the serialization for std::vector is built-in in Boost.Serialization.

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

//change template flags as you are pleased but ring and polygon has to be
//in correspondence w.r.t. to "closed" and "clockwise" policies
typedef boost::geometry::model::ring<MyPoint, false, true> MyRing;
typedef boost::geometry::model::polygon<MyPoint, false, true> MyPolygon; 

namespace  boost {
namespace serialization {

//Default ring<MyPoint> simply inherits from std::vector<MyPoint>, 
//its serialization is trivial and no implementation is needed. 

//Default polygon<MyPoint> gives direct access to outer ring and the container of inner rings
template<class Archive>
void serialize(Archive & ar, MyPolygon& poly, const unsigned int version) {
    ar &  boost::serialization::make_nvp("outer", poly.outer());
    ar &  boost::serialization::make_nvp("inners", poly.inners());
}


} //namespace serialization
} //namespace boost

That's it, you are done, now you can use MyPolygon with Boost.Serialize as any other class:

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

void foo_out(std::ostream & oss, const MyPolygon & poly)
{
    boost::archive::xml_oarchive oa(oss);
    oa & BOOST_SERIALIZATION_NVP(poly);
}

void foo_in(std::istream & iss, MyPolygon & poly)
{
    boost::archive::xml_iarchive ia(iss);
    ia & BOOST_SERIALIZATION_NVP(poly);
}

Enjoy!

OTHER TIPS

Boost.Geometry does not support Boost.Serialization. You can read and write WKT (well-known text), this is a standardized ASCII format used by many databases too. See for example: http://en.wikipedia.org/wiki/Well-known_text

There is also WKB (well-known binary) but that is not yet 100% supported. However, for polygons it is supported.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top