03_polygon_example.cpp

The polygon example shows some examples of what can be done with polygons in the Generic Geometry Library: the outer ring and the inner rings how to calculate the area of a polygon how to get the centroid, and how to get an often more interesting label point how to correct the polygon such that it is clockwise and closed within: the well-known point in polygon algorithm how to use polygons which use another container, or which use different containers for points and for inner rings how polygons can be intersected, or clipped, using a clipping box

The illustrations below show the usage of the within algorithm and the intersection algorithm.

The within algorithm results in true if a point lies completly within a polygon. If it lies exactly on a border it is not considered as within and if it is inside a hole it is also not within the polygon. This is illustrated below, where only the point in the middle is within the polygon.

The clipping algorithm, called intersection, is illustrated below:

The yellow polygon, containing a hole, is clipped with the blue rectangle, resulting in a multi_polygon of three polygons, drawn in red. The hole is vanished.

include polygon_example.cpp

    //Boost.Geometry(akaGGL,GenericGeometryLibrary)

    //Copyright(c)2007-2012BarendGehrels,Amsterdam,theNetherlands.
    //Copyright(c)2008-2012BrunoLalande,Paris,France.
    //Copyright(c)2009-2012MateuszLoskot,London,UK.

    //Use,modificationanddistributionissubjecttotheBoostSoftwareLicense,
    //Version1.0.(SeeaccompanyingfileLICENSE_1_0.txtorcopyat
    //http://www.boost.org/LICENSE_1_0.txt)
    //
    //PolygonExample

    #include<algorithm>//forreverse,unique
    #include<iostream>
    #include<string>

    #include<boost/geometry/geometry.hpp>
    #include<boost/geometry/geometries/point_xy.hpp>
    #include<boost/geometry/geometries/polygon.hpp>
    #include<boost/geometry/geometries/adapted/c_array.hpp>
    #include<boost/geometry/geometries/multi_polygon.hpp>

    BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)

    std::stringboolstr(boolv)
    {
    returnv?"true":"false";
    }

    intmain(void)
    {
    usingnamespaceboost::geometry;

    typedefmodel::d2::point_xy<double>point_2d;
    typedefmodel::polygon<point_2d>polygon_2d;
    typedefmodel::box<point_2d>box_2d;

    //Defineapolygonandfilltheouterring.
    //Inmostcasesyouwillreaditfromafileordatabase
    polygon_2dpoly;
    {
    constdoublecoor[][2]={
    {2.0,1.3},{2.4,1.7},{2.8,1.8},{3.4,1.2},{3.7,1.6},
    {3.4,2.0},{4.1,3.0},{5.3,2.6},{5.4,1.2},{4.9,0.8},{2.9,0.7},
    {2.0,1.3}//closingpointisopeningpoint
    };
    assign_points(poly,coor);
    }

    //Polygonsshouldbeclosed,anddirectedclockwise.Ifyou'renotsureifthatisthecase,
    //callthecorrectalgorithm
    correct(poly);

    //Polygonscanbestreamedastext
    //(ormoreprecisely:asDSV(delimiterseparatedvalues))
    std::cout<<dsv(poly)<<std::endl;

    //Aswithlines,boundingboxofpolygonscanbecalculated
    box_2db;
    envelope(poly,b);
    std::cout<<dsv(b)<<std::endl;

    //Theareaofthepolygoncanbecalulated
    std::cout<<"area:"<<area(poly)<<std::endl;

    //Andthecentroid,whichisthecenterofgravity
    point_2dcent;
    centroid(poly,cent);
    std::cout<<"centroid:"<<dsv(cent)<<std::endl;

    //Thenumberofpointscanberequestedperring(using.size())
    //orperpolygon(usingnum_points)
    std::cout<<"numberofpointsinouterring:"<<poly.outer().size()<<std::endl;

    //Polygonscanhaveoneormoreinnerrings,alsocalledholes,islands,interiorrings.
    //Let'saddone
    {
    poly.inners().resize(1);
    model::ring<point_2d>&inner=poly.inners().back();

    constdoublecoor[][2]={{4.0,2.0},{4.2,1.4},{4.8,1.9},{4.4,2.2},{4.0,2.0}};
    assign_points(inner,coor);
    }

    correct(poly);

    std::cout<<"withinnerring:"<<dsv(poly)<<std::endl;
    //Theareaofthepolygonischangedofcourse
    std::cout<<"newareaofpolygon:"<<area(poly)<<std::endl;
    centroid(poly,cent);
    std::cout<<"newcentroid:"<<dsv(cent)<<std::endl;

    //Youcantestwhetherpointsarewithinapolygon
    std::cout<<"pointinpolygon:"
    <<"p1:"<<boolstr(within(make<point_2d>(3.0,2.0),poly))
    <<"p2:"<<boolstr(within(make<point_2d>(3.7,2.0),poly))
    <<"p3:"<<boolstr(within(make<point_2d>(4.4,2.0),poly))
    <<std::endl;

    //Aswithlinestringsandpoints,youcanderivefrompolygontoadd,forexample,
    //fillcolorandstrokecolor.OrSRID(spatialreferenceID).OrZ-value.Orapropertymap.
    //Wedon'tshowthishere.

    //Clipthepolygonusingabox
    box_2dcb(make<point_2d>(1.5,1.5),make<point_2d>(4.5,2.5));
    typedefstd::vector<polygon_2d>polygon_list;
    polygon_listv;

    intersection(cb,poly,v);
    std::cout<<"Clippedoutputpolygons"<<std::endl;
    for(polygon_list::const_iteratorit=v.begin();it!=v.end();++it)
    {
    std::cout<<dsv(*it)<<std::endl;
    }

    typedefmodel::multi_polygon<polygon_2d>polygon_set;
    polygon_setps;
    union_(cb,poly,ps);

    polygon_2dhull;
    convex_hull(poly,hull);
    std::cout<<"Convexhull:"<<dsv(hull)<<std::endl;

    //Ifyoureallywant:
    //Youdon'thavetouseavector,youcandefineapolygonwithadeque
    //Youcanspecifythecontainerforthepointsandfortheinnerringsindependantly

    typedefmodel::polygon<point_2d, true, true, std::deque, std::deque>deque_polygon;
    deque_polygonpoly2;
    ring_type<deque_polygon>::type&ring=exterior_ring(poly2);
    append(ring,make<point_2d>(2.8,1.9));
    append(ring,make<point_2d>(2.9,2.4));
    append(ring,make<point_2d>(3.3,2.2));
    append(ring,make<point_2d>(3.2,1.8));
    append(ring,make<point_2d>(2.8,1.9));
    std::cout<<dsv(poly2)<<std::endl;

    return0;
    }