Search code examples
c++boostclippingboost-geometry

Boost geometry cartesian2d.hpp


I tried to do this clipping example using Boost Geometry in the example here

But in the newest Boost library I can't find ...

boost/geometry/geometries/cartesian2d.hpp

Does anyone have any idea where I might find this file? Or is this tutorial too old, and the file now obsolete?


Solution

  • The tutorial is too old. Much has changed since that tutorial was written.

    Anyhow, I've modified the code in your link above so that it compiles in Boost ver 1.53.0 ...

    #include <boost/geometry.hpp>
    #include <boost/geometry/geometries/point_xy.hpp>
    #include <boost/geometry/geometries/polygon.hpp>
    #include <boost/geometry/io/wkt/wkt.hpp>
    #include <boost/geometry/multi/geometries/multi_polygon.hpp>
    
    using namespace boost::geometry;
    
    typedef model::d2::point_xy<double> point;
    typedef model::ring< point > ring;
    typedef model::polygon< point > polygon;
    typedef model::multi_polygon< polygon > polygons;
    typedef model::box< point > box;
    
    
    // Define a polygon and fill the outer ring.
    // In most cases you will read it from a file or database
    polygon poly;
    {
      read_wkt("POLYGON((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))", poly);
    }
    
    // Polygons should be closed, and directed clockwise. If you're not sure if that is the case,
    // call the correct algorithm
    correct(poly);
    
    // Polygons can be streamed as text
    // (or more precisely: as DSV (delimiter separated values))
    std::cout << dsv(poly) << std::endl;
    
    // As with lines, bounding box of polygons can be calculated
    box b;
    envelope(poly, b);
    std::cout << dsv(b) << std::endl;
    
    // The area of the polygon can be calulated
    std::cout << "area: " << area(poly) << std::endl;
    
    // And the centroid, which is the center of gravity
    point cent;
    centroid(poly, cent);
    std::cout << "centroid: " << dsv(cent) << std::endl;
    
    
    // The number of points have to called per ring separately
    std::cout << "number of points in outer ring: " << poly.outer().size() << std::endl;
    
    // Polygons can have one or more inner rings, also called holes, donuts, islands, interior rings.
    // Let's add one
    {
        poly.inners().resize(1);
        ring& inner = poly.inners().back();
        read_wkt("POLYGON((4.0 2.0, 4.2 1.4, 4.8 1.9, 4.4 2.2, 4.0 2.0))", inner);
    }
    
    correct(poly);
    
    std::cout << "with inner ring:" << dsv(poly) << std::endl;
    // The area of the polygon is changed of course
    std::cout << "new area of polygon: " << area(poly) << std::endl;
    centroid(poly, cent);
    std::cout << "new centroid: " << dsv(cent) << std::endl;
    
    // You can test whether points are within a polygon
    std::cout << "point in polygon:"
        << " p1: "  << (within(make<point>(3.0, 2.0), poly)?"true":"false")
        << " p2: "  << (within(make<point>(3.7, 2.0), poly)?"true":"false")
        << " p3: "  << (within(make<point>(4.4, 2.0), poly)?"true":"false")
        << std::endl;
    
    // As with linestrings and points, you can derive from polygon to add, for example,
    // fill color and stroke color. Or SRID (spatial reference ID). Or Z-value. Or a property map.
    // We don't show this here.
    
    // Clip the polygon using a bounding box
    box cb(make<point>(1.5, 1.5), make<point>(4.5, 2.5));
    polygons v;
    
    intersection(cb, poly, v);
    std::cout << "Clipped output polygons" << std::endl;
    for (polygons::const_iterator it = v.begin(); it != v.end(); ++it)
    {
        std::cout << dsv(*it) << std::endl;
    }
    
    union_(cb, poly, v);
    
    polygon hull;
    convex_hull(poly, hull);
    std::cout << "Convex hull:" << dsv(hull) << std::endl;
    
    // If you really want:
    //   You don't have to use a vector, you can define a polygon with a deque
    //   You can specify the container for the points and for the inner rings independently
    
    typedef model::polygon<point, true, true, std::vector, std::deque> polygon_deq;
    polygon_deq poly2;
    polygon_deq::ring_type& r = poly2.outer();
    append(r, make<point>(2.8, 1.9));
    append(r, make<point>(2.9, 2.4));
    append(r, make<point>(3.3, 2.2));
    append(r, make<point>(3.2, 1.8));
    append(r, make<point>(2.8, 1.9));
    std::cout << dsv(poly2) << std::endl;