mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-13 12:32:09 +00:00
209 lines
16 KiB
HTML
209 lines
16 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
|
<title>Boost.Geometry (aka GGL, Generic Geometry Library)</title>
|
|
<link href="doxygen.css" rel="stylesheet" type="text/css">
|
|
<link href="tabs.css" rel="stylesheet" type="text/css">
|
|
</head>
|
|
|
|
<table cellpadding="2" width="100%">
|
|
<tbody>
|
|
<tr>
|
|
<td valign="top">
|
|
<img alt="Boost.Geometry" src="images/ggl-logo-big.png" height="80" width="200">
|
|
|
|
</td>
|
|
<td valign="top" align="right">
|
|
<a href="http://www.boost.org">
|
|
<img alt="Boost C++ Libraries" src="images/accepted_by_boost.png" height="80" width="230" border="0">
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<!-- Generated by Doxygen 1.5.9 -->
|
|
<div class="navigation" id="top">
|
|
<div class="tabs">
|
|
<ul>
|
|
<li><a href="index.html"><span>Main Page</span></a></li>
|
|
<li><a href="pages.html"><span>Related Pages</span></a></li>
|
|
<li><a href="modules.html"><span>Modules</span></a></li>
|
|
<li><a href="namespaces.html"><span>Namespaces</span></a></li>
|
|
<li><a href="annotated.html"><span>Classes</span></a></li>
|
|
<li><a href="files.html"><span>Files</span></a></li>
|
|
<li><a href="examples.html"><span>Examples</span></a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="contents">
|
|
<h1>03_polygon_example.cpp</h1>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<p>
|
|
The illustrations below show the usage of the within algorithm and the intersection algorithm.<p>
|
|
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.<p>
|
|
<div align="center">
|
|
<img src="within_polygon.png" alt="within_polygon.png">
|
|
</div>
|
|
<p>
|
|
The clipping algorithm, called intersection, is illustrated below:<p>
|
|
<div align="center">
|
|
<img src="clip_polygon.png" alt="clip_polygon.png">
|
|
</div>
|
|
<p>
|
|
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.<p>
|
|
include polygon_example.cpp<p>
|
|
<div class="fragment"><pre class="fragment"><span class="comment">// Boost.Geometry (aka GGL, Generic Geometry Library)</span>
|
|
<span class="comment">//</span>
|
|
<span class="comment">// Copyright Barend Gehrels 2007-2009, Geodan, Amsterdam, the Netherlands</span>
|
|
<span class="comment">// Copyright Bruno Lalande 2008, 2009</span>
|
|
<span class="comment">// Use, modification and distribution is subject to the Boost Software License,</span>
|
|
<span class="comment">// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at</span>
|
|
<span class="comment">// http://www.boost.org/LICENSE_1_0.txt)</span>
|
|
<span class="comment">//</span>
|
|
<span class="comment">// Polygon Example</span>
|
|
|
|
<span class="preprocessor">#include <algorithm></span> <span class="comment">// for reverse, unique</span>
|
|
<span class="preprocessor">#include <iostream></span>
|
|
<span class="preprocessor">#include <string></span>
|
|
|
|
<span class="preprocessor">#include <boost/geometry/geometry.hpp></span>
|
|
<span class="preprocessor">#include <<a class="code" href="cartesian2d_8hpp.html">boost/geometry/geometries/cartesian2d.hpp</a>></span>
|
|
<span class="preprocessor">#include <<a class="code" href="c__array__cartesian_8hpp.html">boost/geometry/geometries/adapted/c_array_cartesian.hpp</a>></span>
|
|
<span class="preprocessor">#include <<a class="code" href="std__as__linestring_8hpp.html">boost/geometry/geometries/adapted/std_as_linestring.hpp</a>></span>
|
|
<span class="preprocessor">#include <boost/geometry/multi/multi.hpp></span>
|
|
|
|
std::string boolstr(<span class="keywordtype">bool</span> v)
|
|
{
|
|
<span class="keywordflow">return</span> v ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>;
|
|
}
|
|
|
|
<span class="keywordtype">int</span> main(<span class="keywordtype">void</span>)
|
|
{
|
|
<span class="keyword">using namespace </span>boost::geometry;
|
|
|
|
<span class="comment">// Define a polygon and fill the outer ring.</span>
|
|
<span class="comment">// In most cases you will read it from a file or database</span>
|
|
<a name="_a0"></a><a class="code" href="classboost_1_1geometry_1_1polygon.html" title="The polygon contains an outer ring and zero or more inner rings.">polygon_2d</a> poly;
|
|
{
|
|
<span class="keyword">const</span> <span class="keywordtype">double</span> coor[][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} <span class="comment">// closing point is opening point</span>
|
|
};
|
|
<a name="a1"></a><a class="code" href="group__access.html#gd1a7d6277b95439021f13191094aebdb" title="assign two values to a 2D point">assign</a>(poly, coor);
|
|
}
|
|
|
|
<span class="comment">// Polygons should be closed, and directed clockwise. If you're not sure if that is the case,</span>
|
|
<span class="comment">// call the correct algorithm</span>
|
|
<a name="a2"></a><a class="code" href="namespaceboost_1_1geometry.html#35821ea4ae6c850c76bca878ae29623c">correct</a>(poly);
|
|
|
|
<span class="comment">// Polygons can be streamed as text</span>
|
|
<span class="comment">// (or more precisely: as DSV (delimiter separated values))</span>
|
|
std::cout << <a name="a3"></a><a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">dsv</a>(poly) << std::endl;
|
|
|
|
<span class="comment">// As with lines, bounding box of polygons can be calculated</span>
|
|
<a name="_a4"></a><a class="code" href="classboost_1_1geometry_1_1box.html" title="Class box: defines a box made of two describing points.">box_2d</a> b;
|
|
<a name="a5"></a><a class="code" href="group__envelope.html#g47902cb32df49619702452dbdb45c49a" title="Calculate envelope of a geometry.">envelope</a>(poly, b);
|
|
std::cout << <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">dsv</a>(b) << std::endl;
|
|
|
|
<span class="comment">// The area of the polygon can be calulated</span>
|
|
std::cout << <span class="stringliteral">"area: "</span> << <a name="a6"></a><a class="code" href="group__area.html#gd0e9e99685a9d45895162bd1fd96a136" title="Calculate area of a geometry.">area</a>(poly) << std::endl;
|
|
|
|
<span class="comment">// And the centroid, which is the center of gravity</span>
|
|
<a name="_a7"></a><a class="code" href="classboost_1_1geometry_1_1point__xy.html" title="2D point in Cartesian coordinate system">point_2d</a> cent;
|
|
<a name="a8"></a><a class="code" href="group__centroid.html#g7f67098dd56aba656f32b3635b66d105" title="Calculate centroid using a specified strategy.">centroid</a>(poly, cent);
|
|
std::cout << <span class="stringliteral">"centroid: "</span> << <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">dsv</a>(cent) << std::endl;
|
|
|
|
|
|
<span class="comment">// The number of points can be requested per ring (using .size())</span>
|
|
<span class="comment">// or per polygon (using num_points)</span>
|
|
std::cout << <span class="stringliteral">"number of points in outer ring: "</span> << poly.<a name="a9"></a><a class="code" href="classboost_1_1geometry_1_1polygon.html#a0efb41fda66b78d48cfc45a1753b05a">outer</a>().size() << std::endl;
|
|
|
|
<span class="comment">// Polygons can have one or more inner rings, also called holes, donuts, islands, interior rings.</span>
|
|
<span class="comment">// Let's add one</span>
|
|
{
|
|
poly.<a name="a10"></a><a class="code" href="classboost_1_1geometry_1_1polygon.html#f2193847220f83dead7633a9c5ef5833">inners</a>().resize(1);
|
|
<a name="_a11"></a><a class="code" href="classboost_1_1geometry_1_1linear__ring.html" title="A linear_ring (linear linear_ring) is a closed line which should not be selfintersecting...">linear_ring<point_2d></a>& inner = poly.<a class="code" href="classboost_1_1geometry_1_1polygon.html#f2193847220f83dead7633a9c5ef5833">inners</a>().back();
|
|
|
|
<span class="keyword">const</span> <span class="keywordtype">double</span> coor[][2] = { {4.0, 2.0}, {4.2, 1.4}, {4.8, 1.9}, {4.4, 2.2}, {4.0, 2.0} };
|
|
<a class="code" href="group__access.html#gd1a7d6277b95439021f13191094aebdb" title="assign two values to a 2D point">assign</a>(inner, coor);
|
|
}
|
|
|
|
<a class="code" href="namespaceboost_1_1geometry.html#35821ea4ae6c850c76bca878ae29623c">correct</a>(poly);
|
|
|
|
std::cout << <span class="stringliteral">"with inner ring:"</span> << <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">dsv</a>(poly) << std::endl;
|
|
<span class="comment">// The area of the polygon is changed of course</span>
|
|
std::cout << <span class="stringliteral">"new area of polygon: "</span> << <a class="code" href="group__area.html#gd0e9e99685a9d45895162bd1fd96a136" title="Calculate area of a geometry.">area</a>(poly) << std::endl;
|
|
<a class="code" href="group__centroid.html#g7f67098dd56aba656f32b3635b66d105" title="Calculate centroid using a specified strategy.">centroid</a>(poly, cent);
|
|
std::cout << <span class="stringliteral">"new centroid: "</span> << <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">dsv</a>(cent) << std::endl;
|
|
|
|
<span class="comment">// You can test whether points are within a polygon</span>
|
|
std::cout << <span class="stringliteral">"point in polygon:"</span>
|
|
<< <span class="stringliteral">" p1: "</span> << boolstr(<a name="a12"></a><a class="code" href="group__within.html#ge8d7fe4e3391e7e0cadf14cc23b7cec1" title="Within, examine if a geometry is within another geometry.">within</a>(make<point_2d>(3.0, 2.0), poly))
|
|
<< <span class="stringliteral">" p2: "</span> << boolstr(<a class="code" href="group__within.html#ge8d7fe4e3391e7e0cadf14cc23b7cec1" title="Within, examine if a geometry is within another geometry.">within</a>(make<point_2d>(3.7, 2.0), poly))
|
|
<< <span class="stringliteral">" p3: "</span> << boolstr(<a class="code" href="group__within.html#ge8d7fe4e3391e7e0cadf14cc23b7cec1" title="Within, examine if a geometry is within another geometry.">within</a>(make<point_2d>(4.4, 2.0), poly))
|
|
<< std::endl;
|
|
|
|
<span class="comment">// As with linestrings and points, you can derive from polygon to add, for example,</span>
|
|
<span class="comment">// fill color and stroke color. Or SRID (spatial reference ID). Or Z-value. Or a property map.</span>
|
|
<span class="comment">// We don't show this here.</span>
|
|
|
|
<span class="comment">// Clip the polygon using a bounding box</span>
|
|
<a class="code" href="classboost_1_1geometry_1_1box.html" title="Class box: defines a box made of two describing points.">box_2d</a> cb(make<point_2d>(1.5, 1.5), make<point_2d>(4.5, 2.5));
|
|
<span class="keyword">typedef</span> std::vector<polygon_2d > polygon_list;
|
|
polygon_list v;
|
|
|
|
intersection_inserter<polygon_2d>(cb, poly, std::back_inserter(v));
|
|
std::cout << <span class="stringliteral">"Clipped output polygons"</span> << std::endl;
|
|
<span class="keywordflow">for</span> (polygon_list::const_iterator it = v.begin(); it != v.end(); ++it)
|
|
{
|
|
std::cout << <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">dsv</a>(*it) << std::endl;
|
|
}
|
|
|
|
<span class="keyword">typedef</span> <a name="_a13"></a><a class="code" href="structboost_1_1geometry_1_1multi__polygon.html" title="multi_polygon, a collection of polygons">multi_polygon<polygon_2d></a> polygon_set;
|
|
polygon_set ps;
|
|
union_inserter<polygon_2d>(cb, poly, std::back_inserter(ps));
|
|
|
|
<a class="code" href="classboost_1_1geometry_1_1polygon.html" title="The polygon contains an outer ring and zero or more inner rings.">polygon_2d</a> hull;
|
|
<a name="a14"></a><a class="code" href="namespaceboost_1_1geometry.html#dc3a1eff51c809466fdfeb14a820be8a">convex_hull</a>(poly, hull);
|
|
std::cout << <span class="stringliteral">"Convex hull:"</span> << <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">dsv</a>(hull) << std::endl;
|
|
|
|
<span class="comment">// If you really want:</span>
|
|
<span class="comment">// You don't have to use a vector, you can define a polygon with a deque</span>
|
|
<span class="comment">// You can specify the container for the points and for the inner rings independantly</span>
|
|
|
|
<span class="keyword">typedef</span> <a class="code" href="classboost_1_1geometry_1_1polygon.html" title="The polygon contains an outer ring and zero or more inner rings.">polygon<point_2d, std::vector, std::deque></a> polygon_type;
|
|
polygon_type poly2;
|
|
<a name="_a15"></a><a class="code" href="structboost_1_1geometry_1_1ring__type.html" title="Meta-function which defines ring type of (multi)polygon geometry.">ring_type<polygon_type>::type</a>& ring = <a name="a16"></a><a class="code" href="group__access.html#gd96ba07cd3c6c3216bd5ab69adc9ccb5" title="Function to get the exterior_ring ring of a polygon.">exterior_ring</a>(poly2);
|
|
<a name="a17"></a><a class="code" href="group__access.html#gaa82516f99aff50c0f96dcc945cf73cb" title="Appends one or more points to a linestring, ring, polygon, multi.">append</a>(ring, make<point_2d>(2.8, 1.9));
|
|
<a class="code" href="group__access.html#gaa82516f99aff50c0f96dcc945cf73cb" title="Appends one or more points to a linestring, ring, polygon, multi.">append</a>(ring, make<point_2d>(2.9, 2.4));
|
|
<a class="code" href="group__access.html#gaa82516f99aff50c0f96dcc945cf73cb" title="Appends one or more points to a linestring, ring, polygon, multi.">append</a>(ring, make<point_2d>(3.3, 2.2));
|
|
<a class="code" href="group__access.html#gaa82516f99aff50c0f96dcc945cf73cb" title="Appends one or more points to a linestring, ring, polygon, multi.">append</a>(ring, make<point_2d>(3.2, 1.8));
|
|
<a class="code" href="group__access.html#gaa82516f99aff50c0f96dcc945cf73cb" title="Appends one or more points to a linestring, ring, polygon, multi.">append</a>(ring, make<point_2d>(2.8, 1.9));
|
|
std::cout << <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">dsv</a>(poly2) << std::endl;
|
|
|
|
<span class="keywordflow">return</span> 0;
|
|
}
|
|
</pre></div> </div>
|
|
<hr size="1">
|
|
<table width="100%">
|
|
<tbody>
|
|
<tr>
|
|
<td align="left"><small>
|
|
<p>December 1, 2009</p>
|
|
</small></td>
|
|
<td align="right">
|
|
<small>Copyright © 1995-2009 Barend Gehrels, Geodan, Amsterdam<br>
|
|
Copyright © 2008-2009 Bruno Lalande, Paris<br>
|
|
Copyright © 2009 Mateusz Loskot, Cadcorp, London<br>
|
|
</small>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<address style="text-align: right;"><small>
|
|
Documentation is generated by <a href="http://www.doxygen.org/index.html">Doxygen</a>
|
|
</small></address>
|
|
</body>
|
|
</html>
|