06_b_transformation_example.cpp

    //Boost.Geometry(akaGGL,GenericGeometryLibrary)
    //Example:AffineTransformation(translate,scale,rotate)
    //
    //Copyright(c)2009-2012MateuszLoskot,London,UK.
    //
    //Use,modificationanddistributionissubjecttotheBoostSoftwareLicense,
    //Version1.0.(SeeaccompanyingfileLICENSE_1_0.txtorcopyat
    //http://www.boost.org/LICENSE_1_0.txt)

    #include<ctime>//forstd::time
    #include<algorithm>
    #include<fstream>
    #include<iostream>
    #include<limits>
    #include<sstream>

    #include<boost/geometry/geometry.hpp>
    #include<boost/geometry/geometries/point_xy.hpp>
    #include<boost/geometry/geometries/polygon.hpp>
    #include<boost/geometry/algorithms/centroid.hpp>
    #include<boost/geometry/strategies/transform.hpp>
    #include<boost/geometry/strategies/transform/matrix_transformers.hpp>
    #include<boost/geometry/io/wkt/read.hpp>

    #ifdefined(HAVE_SVG)
    #include<boost/geometry/io/svg/write_svg.hpp>
    #endif

    #include<boost/random.hpp>
    #include<boost/range.hpp>
    #include<boost/shared_ptr.hpp>

    usingnamespaceboost::geometry;

    structrandom_style
    {
    random_style()
    :rng(static_cast<int>(std::time(0))),dist(0,255),colour(rng,dist)
    {}

    std::stringfill(doubleopacity=1)
    {
    std::ostringstreamoss;
    oss<<"fill:rgba("<<colour()<<","<<colour()<<","<<colour()<<","<<opacity<<");";
    returnoss.str();
    }

    std::stringstroke(intwidth,doubleopacity=1)
    {
    std::ostringstreamoss;
    oss<<"stroke:rgba("<<colour()<<","<<colour()<<","<<colour()<<","<<opacity<<");";
    oss<<"stroke-width:"<<width<<";";
    returnoss.str();
    }

    template<typenameT>
    std::stringtext(Tx,Ty,std::stringconst&text)
    {
    std::ostringstreamoss;
    oss<<"<textx=\""<<static_cast<int>(x)-90<<"\"y=\""<<static_cast<int>(y)<<"\"font-family=\"Verdana\">"<<text<<"</text>";
    returnoss.str();
    }

    boost::mt19937rng;
    boost::uniform_int<>dist;
    boost::variate_generator<boost::mt19937&,boost::uniform_int<>>colour;
    };

    template<typenameOutputStream>
    structsvg_output
    {
    svg_output(OutputStream&os,doubleopacity=1):os(os),opacity(opacity)
    {
    os<<"<?xmlversion=\"1.0\"standalone=\"no\"?>\n"
    <<"<!DOCTYPEsvgPUBLIC\"-//W3C//DTDSVG1.1//EN\"\n"
    <<"\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"
    <<"<svgwidth=\"100%\"height=\"100%\"version=\"1.1\"\n"
    <<"xmlns=\"http://www.w3.org/2000/svg\">"<<std::endl;
    }

    ~svg_output()
    {
    os<<"</svg>"<<std::endl;
    }

    template<typenameG>
    voidput(Gconst&g,std::stringconst&label)
    {
    std::stringstyle_str(style.fill(opacity)+style.stroke(5,opacity));
    #ifdefined(HAVE_SVG)
    os<<boost::geometry::svg(g,style_str)<<std::endl;
    #endif
    if(!label.empty())
    {
    typenamepoint_type<G>::typec;
    centroid(g,c);
    os<<style.text(static_cast<int>(get<0>(c)),static_cast<int>(get<1>(c)),label);
    }
    }

    private:

    OutputStream&os;
    doubleopacity;
    random_stylestyle;
    };

    intmain()
    {
    usingnamespaceboost::geometry::strategy::transform;

    typedefboost::geometry::model::d2::point_xy<double>point_2d;

    try
    {
    std::stringfile("06_b_transformation_example.svg");
    std::ofstreamofs(file.c_str());
    svg_output<std::ofstream>svg(ofs,0.5);

    //G1-createsubjectforaffinetransformations
    model::polygon<point_2d>g1;
    read_wkt("POLYGON((50250,400250,15050,50250))",g1);
    std::clog<<"sourcebox:\t"<<boost::geometry::dsv(g1)<<std::endl;
    svg.put(g1,"g1");

    //G1-Translate->G2
    translate_transformer<double, 2, 2>translate(0,250);
    model::polygon<point_2d>g2;
    transform(g1,g2,translate);
    std::clog<<"translated:\t"<<boost::geometry::dsv(g2)<<std::endl;
    svg.put(g2,"g2=g1.translate(0,250)");

    //G2-Scale->G3
    scale_transformer<double, 2, 2>scale(0.5,0.5);
    model::polygon<point_2d>g3;
    transform(g2,g3,scale);
    std::clog<<"scaled:\t"<<boost::geometry::dsv(g3)<<std::endl;
    svg.put(g3,"g3=g2.scale(0.5,0.5)");

    //G3-Combinerotateandtranslate->G4
    rotate_transformer<degree, double, 2, 2>rotate(45);

    //Composematrixforthetwotransformation
    //Createtransformerattachedtothetransformationmatrix
    ublas_transformer<double, 2, 2>
    combined(boost::numeric::ublas::prod(rotate.matrix(),translate.matrix()));
    //combined(rotate.matrix());

    //Applytransformationtosubjectgeometrypoint-by-point
    model::polygon<point_2d>g4;
    transform(g3,g4,combined);

    std::clog<<"rotated&translated:\t"<<boost::geometry::dsv(g4)<<std::endl;
    svg.put(g4,"g4=g3.(rotate(45)*translate(0,250))");

    std::clog<<"SavedSVGfile:\t"<<file<<std::endl;
    }
    catch(std::exceptionconst&e)
    {
    std::cerr<<e.what()<<std::endl;
    }
    catch(...)
    {
    std::cerr<<"unknownerror"<<std::endl;
    }
    return0;
    }