...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
This Quick Start section shows some of the features of Boost.Geometry in the form of annotated, relatively simple, code snippets.
The code below assumes that boost/geometry.hpp
is included,
and that namespace boost::geometry
is used. Boost.Geometry is header only, so including headerfiles is enough.
There is no linking with any library necessary.
#include <boost/geometry.hpp> #include <boost/geometry/geometries/point_xy.hpp> #include <boost/geometry/geometries/polygon.hpp> using namespace boost::geometry;
It is possible to use only a small part of the library. For example: the distance between two points is a common use case. Boost.Geometry can calculate it from various types. Using one of its own types:
model::d2::point_xy<int> p1(1, 1), p2(2, 2); std::cout << "Distance p1-p2 is: " << distance(p1, p2) << std::endl;
If the right headers are included and the types are bound to a coordinate system, various other types can be used as points: plain C array's, Boost.Array's, Boost.Tuple's, Boost.Fusion imported structs, your own classes...
Registering and using a C array:
#include <boost/geometry/geometries/adapted/c_array.hpp> BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)
int a[2] = {1,1}; int b[2] = {2,3}; double d = distance(a, b); std::cout << "Distance a-b is: " << d << std::endl;
Another often used algorithm is point-in-polygon. It is implemented in Boost.Geometry
under the name within
. We show
its usage here checking a Boost.Tuple (as a point) located within a polygon,
filled with C Array point pairs.
But it is first necessary to register a Boost.Tuple, like the C array:
#include <boost/geometry/geometries/adapted/boost_tuple.hpp> BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
double points[][2] = {{2.0, 1.3}, {4.1, 3.0}, {5.3, 2.6}, {2.9, 0.7}, {2.0, 1.3}}; model::polygon<model::d2::point_xy<double> > poly; append(poly, points); boost::tuple<double, double> p = boost::make_tuple(3.7, 2.0); std::cout << "Point p is in polygon? " << std::boolalpha << within(p, poly) << std::endl;
We can calculate the area of a polygon:
std::cout << "Area: " << area(poly) << std::endl;
By the nature of a template library, it is possible to mix point types. We calculate distance again, now using a C array point and a Boost.Tuple point:
double d2 = distance(a, p); std::cout << "Distance a-p is: " << d2 << std::endl;
The snippets listed above generate the following output:
Distance p1-p2 is: 1.41421 Distance a-b is: 2.23607 Point p is in polygon? true Area: 3.015 Distance a-p is: 2.87924
It is also possible to use non-Cartesian points. For example: points on a sphere. When then an algorithm such as distance is used the library "inspects" that it is handling spherical points and calculates the distance over the sphere, instead of applying the Pythagorean theorem.
Note | |
---|---|
Boost.Geometry supports a geographical coordinate system, but that is in an extension and not released in the current Boost release. |
We approximate the Earth as a sphere and calculate the distance between Amsterdam and Paris:
typedef boost::geometry::model::point < double, 2, boost::geometry::cs::spherical_equatorial<boost::geometry::degree> > spherical_point; spherical_point amsterdam(4.90, 52.37); spherical_point paris(2.35, 48.86); double const earth_radius = 3959; // miles std::cout << "Distance in miles: " << distance(amsterdam, paris) * earth_radius << std::endl;
It writes:
Distance in miles: 267.02
Finally an example from a totally different domain: developing window-based applications, for example using QtWidgets. As soon as Qt classes are registered in Boost.Geometry we can use them. We can, for example, check if two rectangles overlap and if so, move the second one to another place:
QRect r1(100, 200, 15, 15); QRect r2(110, 210, 20, 20); if (overlaps(r1, r2)) { assign_values(r2, 200, 300, 220, 320); }
In the reference many more examples can be found.