4

I look at grate library called Boost Geometry I look at it but see no tutorials on working with anything at least a bit graphical. So I wonder if any one can help providing a simple tutorial on creating some N random poligons (random in color size and form) and saving tham as vector image like SVG?

genpfault
  • 47,669
  • 9
  • 68
  • 119
Rella
  • 59,216
  • 102
  • 341
  • 614
  • This might help: https://svn.boost.org/trac/boost/wiki/LibrariesUnderConstruction#Boost.Plot – AraK Nov 07 '11 at 16:35

2 Answers2

11

So... solved it: on google you can find this old code. It will not compile with latest boost 1.47.0. So you will try to fix it and you'd get here for example on some outdated docs... so long story short here is what you shall do to make it work:

Download 3 code files for boost/geometry/extensions/io/svg/, they are header only so no wories here.

and now you can compile fixed, updated for current boost code:

#include <iostream>
#include <fstream>
#include <boost/assign.hpp>

#include <boost/algorithm/string.hpp>
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/io/svg/write_svg.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/algorithms/envelope.hpp>

#include <boost/geometry/io/svg/write_svg.hpp>


template <typename Geometry1, typename Geometry2>
void create_svg(std::string const& filename, Geometry1 const& a, Geometry2 const& b)
{
    typedef typename boost::geometry::point_type<Geometry1>::type point_type;
    std::ofstream svg(filename.c_str());

    boost::geometry::svg_mapper<point_type> mapper(svg, 400, 400);
    mapper.add(a);
    mapper.add(b);

    mapper.map(a, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2");
    mapper.map(b, "opacity:0.8;fill:none;stroke:rgb(255,128,0);stroke-width:4;stroke-dasharray:1,7;stroke-linecap:round");
}

int main()
{
    using namespace boost::assign;


    boost::geometry::model::ring<boost::geometry::model::d2::point_xy<double> > ring;
    ring +=
        boost::geometry::model::d2::point_xy<double>(4.0, -0.5), boost::geometry::model::d2::point_xy<double>(3.5, 1.0),
        boost::geometry::model::d2::point_xy<double>(2.0, 1.5), boost::geometry::model::d2::point_xy<double>(3.5, 2.0),
        boost::geometry::model::d2::point_xy<double>(4.0, 3.5), boost::geometry::model::d2::point_xy<double>(4.5, 2.0),
        boost::geometry::model::d2::point_xy<double>(6.0, 1.5), boost::geometry::model::d2::point_xy<double>(4.5, 1.0),
        boost::geometry::model::d2::point_xy<double>(4.0, -0.5);


     boost::geometry::model::box<boost::geometry::model::d2::point_xy<double> > box;
     boost::geometry::envelope(ring, box); 
    std::cout
        << "make_envelope:"
        << boost::geometry::dsv(box)
        << std::endl;

    create_svg("make_envelope.svg", ring, box);
}

this will draw this:

enter image description here

(not image but vector svg file openable in google chrome=)) So this is how to create SVG file from vector in C++=)

Catskul
  • 15,635
  • 13
  • 75
  • 111
Rella
  • 59,216
  • 102
  • 341
  • 614
  • +1 ty for posting this! Looks like the boost::geometry is still in transition as that directory still doesn't exist in 1.48. – kfmfe04 Feb 08 '12 at 11:18
  • @Rella Is there a corresponding a read() operation? That is, if I draw a polygon in svg, how can I read it into a boost::geometry::model::polygon? – David Doria Aug 06 '16 at 11:16
  • modern versions of boost don't work without a little modification. I'll edit this answer with those. – Catskul Jun 30 '18 at 01:48
0

For versions of boost >= 1.54 we now official support from the library under boost::geometry::io::svg.

#include <string>
#include <fstream>

#include <boost/geometry.hpp>


namespace bg = boost::geometry;
namespace bgm = boost::geometry::model;

using Point2D = bgm::d2::point_xy<double>;
using Polygon2D = bgm::polygon<Point2D>;


template <typename Geometry>
void create_svg(std::string const& file_path, Geometry const& geometry, std::string const& style) {
    using PointType = typename bg::point_type<Geometry>::type;
    std::ofstream svg_file(file_path.c_str());
    bg::svg_mapper<PointType> mapper(svg_file, 400, 400);
    mapper.add(geometry);
    mapper.map(geometry, style);
}

Polygon2D create_polygon(Point2D const& p1, Point2D const& p2, Point2D const& p3, Point2D const& p4) {
    // NOTE: For closed poly first point equal to the last
    return {{p1, p2, p3, p4, p1}};
}

int main() {
    auto const& polygon = create_polygon({0., 0.}, {0., 4.}, {7., 4.}, {7., 0.});
    std::string style{"fill-rule:nonzero;fill-opacity:0.5;fill:yellow;stroke:black;stroke-width:2;"};
    create_svg("image.svg", polygon, style);
    return 0;
}

which gives us

enter image description here

Full code for playing is available here.

Daniel
  • 738
  • 6
  • 18