Files
geometry/doc/doxygen_output/html/02__linestring__example_8cpp-example.html
Barend Gehrels 363580fbf6 Added old doxygen docs
[SVN r59777]
2010-02-20 15:57:12 +00:00

277 lines
21 KiB
HTML
Raw Blame History

<!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">
&nbsp;&nbsp;
</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&nbsp;Page</span></a></li>
<li><a href="pages.html"><span>Related&nbsp;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>02_linestring_example.cpp</h1>The linestring example shows how linestrings can be declared and used and shows some more algorithms. One of the important concepts of the Generic Geometry Library is that it is totally built upon the standard library, using the standard containers such as std::vector.<p>
A linestring is, as explained elsewhere in this documentation, not much more than a vector of points. Most algorithms run on linestrings, but can also run on any iterator pair. And all algorithms on std::vector can be used on geometry::linestring.<p>
The sample shows this, shows some algorithms:<ul>
<li>geometry::envelope</li><li>geometry::length</li><li>geometry::distance</li><li>geometry::simplify</li><li>geometry::for_each</li><li>geometry::intersection</li></ul>
<p>
This documentation illustrates the simplify algorithm and the intersection algorithm with some pictures.<p>
The simplify algorithm simplifies a linestring. Simplification means that the less important points are removed from the line and that the points that are most important for the shape of a line are kept. Simplification is done using the well known Douglas Peucker algorithm. The library user can specify the distance or tolerance, which indicates how much the linestring should be simplified.<p>
The image below shows the original and simplified linestring: <div align="center">
<img src="simplify_linestring.png" alt="simplify_linestring.png">
</div>
The blue line is the original linestring; the red line is the simplified line which has one point less. In geographical applications simplification can reduce a linestring to its basic form containing only 10% of its original points.<p>
The intersection algorithm intersects two geometries which each other, delivering a third geometry. In the case of the example a linestring is intersected with a box. Intersection with a box is often called a clip. The image below illustrates the intersection. <div align="center">
<img src="clip_linestring.png" alt="clip_linestring.png">
</div>
The yellow line is intersected with the blue box. The intersection result, painted in red, contains three linestrings.<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">// Linestring Example</span>
<span class="preprocessor">#include &lt;algorithm&gt;</span> <span class="comment">// for reverse, unique</span>
<span class="preprocessor">#include &lt;iostream&gt;</span>
<span class="preprocessor">#include &lt;iterator&gt;</span>
<span class="preprocessor">#include &lt;utility&gt;</span>
<span class="preprocessor">#include &lt;vector&gt;</span>
<span class="preprocessor">#include &lt;boost/geometry/geometry.hpp&gt;</span>
<span class="preprocessor">#include &lt;<a class="code" href="cartesian2d_8hpp.html">boost/geometry/geometries/cartesian2d.hpp</a>&gt;</span>
<span class="comment">// Optional includes to handle c-arrays as points, std::vectors as linestrings</span>
<span class="preprocessor">#include &lt;<a class="code" href="c__array__cartesian_8hpp.html">boost/geometry/geometries/adapted/c_array_cartesian.hpp</a>&gt;</span>
<span class="preprocessor">#include &lt;<a class="code" href="std__as__linestring_8hpp.html">boost/geometry/geometries/adapted/std_as_linestring.hpp</a>&gt;</span>
<span class="keyword">template</span>&lt;<span class="keyword">typename</span> P&gt;
<span class="keyword">inline</span> <span class="keywordtype">void</span> translate_function(P&amp; p)
{
p.x(p.x() + 100.0);
}
<span class="keyword">template</span>&lt;<span class="keyword">typename</span> P&gt;
<span class="keyword">struct </span>scale_functor
{
<span class="keyword">inline</span> <span class="keywordtype">void</span> operator()(P&amp; p)
{
p.x(p.x() * 1000.0);
p.y(p.y() * 1000.0);
}
};
<span class="keywordtype">int</span> main(<span class="keywordtype">void</span>)
{
<span class="keyword">using namespace </span>boost::geometry;
<span class="comment">// Define a linestring, which is a vector of points, and add some points</span>
<span class="comment">// (we add them deliberately in different ways)</span>
<a name="_a0"></a><a class="code" href="classboost_1_1geometry_1_1linestring.html" title="A linestring (named so by OGC) is a collection (default a vector) of points.">linestring_2d</a> ls;
<span class="comment">// points can be created using "make" and added to a linestring using the std:: "push_back"</span>
ls.push_back(make&lt;point_2d&gt;(1.1, 1.1));
<span class="comment">// points can also be assigned using "assign" and added to a linestring using "append"</span>
<a name="_a1"></a><a class="code" href="classboost_1_1geometry_1_1point__xy.html" title="2D point in Cartesian coordinate system">point_2d</a> lp;
<a name="a2"></a><a class="code" href="group__access.html#gd1a7d6277b95439021f13191094aebdb" title="assign two values to a 2D point">assign</a>(lp, 2.5, 2.1);
<a name="a3"></a><a class="code" href="group__access.html#gaa82516f99aff50c0f96dcc945cf73cb" title="Appends one or more points to a linestring, ring, polygon, multi.">append</a>(ls, lp);
<span class="comment">// Lines can be streamed using DSV (delimiter separated values)</span>
std::cout &lt;&lt; <a name="a4"></a><a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">boost::geometry::dsv</a>(ls) &lt;&lt; std::endl;
<span class="comment">// The bounding box of linestrings can be calculated</span>
<a name="_a5"></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="a6"></a><a class="code" href="group__envelope.html#g47902cb32df49619702452dbdb45c49a" title="Calculate envelope of a geometry.">envelope</a>(ls, b);
std::cout &lt;&lt; <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">boost::geometry::dsv</a>(b) &lt;&lt; std::endl;
<span class="comment">// The length of the line can be calulated</span>
std::cout &lt;&lt; <span class="stringliteral">"length: "</span> &lt;&lt; <a name="a7"></a><a class="code" href="group__length.html#g1537537131cd91037cf3ad9fd80d50f1" title="Calculate length of a geometry.">length</a>(ls) &lt;&lt; std::endl;
<span class="comment">// All things from std::vector can be called, because a linestring is a vector</span>
std::cout &lt;&lt; <span class="stringliteral">"number of points 1: "</span> &lt;&lt; ls.size() &lt;&lt; std::endl;
<span class="comment">// All things from boost ranges can be called because a linestring is considered as a range</span>
std::cout &lt;&lt; <span class="stringliteral">"number of points 2: "</span> &lt;&lt; boost::size(ls) &lt;&lt; std::endl;
<span class="comment">// Generic function from geometry/OGC delivers the same value</span>
std::cout &lt;&lt; <span class="stringliteral">"number of points 3: "</span> &lt;&lt; <a name="a8"></a><a class="code" href="group__access.html#g1895ea653bf59866650b18cdb047eed1" title="get number of points">num_points</a>(ls) &lt;&lt; std::endl;
<span class="comment">// The distance from a point to a linestring can be calculated</span>
<a class="code" href="classboost_1_1geometry_1_1point__xy.html" title="2D point in Cartesian coordinate system">point_2d</a> p(1.9, 1.2);
std::cout &lt;&lt; <span class="stringliteral">"distance of "</span> &lt;&lt; <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">boost::geometry::dsv</a>(p)
&lt;&lt; <span class="stringliteral">" to line: "</span> &lt;&lt; <a name="a9"></a><a class="code" href="group__distance.html#g8fb8022d64a75b24c80a64ba46ec4738" title="Calculate distance between two geometries with a specified strategy.">distance</a>(p, ls) &lt;&lt; std::endl;
<span class="comment">// A linestring is a vector. However, some algorithms consider "segments",</span>
<span class="comment">// which are the line pieces between two points of a linestring.</span>
<span class="keywordtype">double</span> d = <a class="code" href="group__distance.html#g8fb8022d64a75b24c80a64ba46ec4738" title="Calculate distance between two geometries with a specified strategy.">distance</a>(p, <a name="_a10"></a><a class="code" href="classboost_1_1geometry_1_1segment.html" title="Class segment: small class containing two (templatized) point references.">segment&lt;point_2d &gt;</a>(ls.front(), ls.back()));
std::cout &lt;&lt; <span class="stringliteral">"distance: "</span> &lt;&lt; d &lt;&lt; std::endl;
<span class="comment">// Add some three points more, let's do it using a classic array.</span>
<span class="comment">// (See documentation for picture of this linestring)</span>
<span class="keyword">const</span> <span class="keywordtype">double</span> c[][2] = { {3.1, 3.1}, {4.9, 1.1}, {3.1, 1.9} };
<a class="code" href="group__access.html#gaa82516f99aff50c0f96dcc945cf73cb" title="Appends one or more points to a linestring, ring, polygon, multi.">append</a>(ls, c);
std::cout &lt;&lt; <span class="stringliteral">"appended: "</span> &lt;&lt; <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">boost::geometry::dsv</a>(ls) &lt;&lt; std::endl;
<span class="comment">// Output as iterator-pair on a vector</span>
{
std::vector&lt;point_2d&gt; v;
std::copy(ls.begin(), ls.end(), std::back_inserter(v));
std::cout
&lt;&lt; <span class="stringliteral">"as vector: "</span>
&lt;&lt; <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">boost::geometry::dsv</a>(v)
&lt;&lt; std::endl;
std::cout
&lt;&lt; <span class="stringliteral">"as it-pair: "</span>
&lt;&lt; <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">boost::geometry::dsv</a>(std::make_pair(v.begin(), v.end()))
&lt;&lt; std::endl;
}
<span class="comment">// All algorithms from std can be used: a linestring is a vector</span>
std::reverse(ls.begin(), ls.end());
std::cout &lt;&lt; <span class="stringliteral">"reversed: "</span> &lt;&lt; <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">boost::geometry::dsv</a>(ls) &lt;&lt; std::endl;
std::reverse(boost::begin(ls), boost::end(ls));
<span class="comment">// The other way, using a vector instead of a linestring, is also possible</span>
std::vector&lt;point_2d&gt; pv(ls.begin(), ls.end());
std::cout &lt;&lt; <span class="stringliteral">"length: "</span> &lt;&lt; <a class="code" href="group__length.html#g1537537131cd91037cf3ad9fd80d50f1" title="Calculate length of a geometry.">length</a>(pv) &lt;&lt; std::endl;
<span class="comment">// If there are double points in the line, you can use unique to remove them</span>
<span class="comment">// So we add the last point, print, make a unique copy and print</span>
{
<span class="comment">// (sidenote, we have to make copies, because</span>
<span class="comment">// ls.push_back(ls.back()) often succeeds but</span>
<span class="comment">// IS dangerous and erroneous!</span>
<a class="code" href="classboost_1_1geometry_1_1point__xy.html" title="2D point in Cartesian coordinate system">point_2d</a> last = ls.back(), first = ls.front();
ls.push_back(last);
ls.insert(ls.begin(), first);
}
std::cout &lt;&lt; <span class="stringliteral">"extra duplicate points: "</span> &lt;&lt; <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">boost::geometry::dsv</a>(ls) &lt;&lt; std::endl;
{
<a class="code" href="classboost_1_1geometry_1_1linestring.html" title="A linestring (named so by OGC) is a collection (default a vector) of points.">linestring_2d</a> ls_copy;
std::unique_copy(ls.begin(), ls.end(), std::back_inserter(ls_copy),
<a name="_a11"></a><a class="code" href="structboost_1_1geometry_1_1equal__to.html" title="Equal To functor, to compare if points are equal.">boost::geometry::equal_to&lt;point_2d&gt;</a>());
ls = ls_copy;
std::cout &lt;&lt; <span class="stringliteral">"uniquecopy: "</span> &lt;&lt; <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">boost::geometry::dsv</a>(ls) &lt;&lt; std::endl;
}
<span class="comment">// Lines can be simplified. This removes points, but preserves the shape</span>
<a class="code" href="classboost_1_1geometry_1_1linestring.html" title="A linestring (named so by OGC) is a collection (default a vector) of points.">linestring_2d</a> ls_simplified;
<a name="a12"></a><a class="code" href="group__simplify.html#gf44556d83e87be316b7dc26ca921af8b" title="Simplify a geometry using a specified strategy.">simplify</a>(ls, ls_simplified, 0.5);
std::cout &lt;&lt; <span class="stringliteral">"simplified: "</span> &lt;&lt; <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">boost::geometry::dsv</a>(ls_simplified) &lt;&lt; std::endl;
<span class="comment">// for_each:</span>
<span class="comment">// 1) Lines can be visited with std::for_each</span>
<span class="comment">// 2) for_each_point is also defined for all geometries</span>
<span class="comment">// 3) for_each_segment is defined for all geometries to all segments</span>
<span class="comment">// 4) loop is defined for geometries to visit segments</span>
<span class="comment">// with state apart, and to be able to break out (not shown here)</span>
{
<a class="code" href="classboost_1_1geometry_1_1linestring.html" title="A linestring (named so by OGC) is a collection (default a vector) of points.">linestring_2d</a> lscopy = ls;
std::for_each(lscopy.begin(), lscopy.end(), translate_function&lt;point_2d&gt;);
<a name="a13"></a><a class="code" href="group__for__each.html#gedf035663317c093e33e65369d302acc" title="Calls functor for geometry.">for_each_point</a>(lscopy, scale_functor&lt;point_2d&gt;());
<a class="code" href="group__for__each.html#gedf035663317c093e33e65369d302acc" title="Calls functor for geometry.">for_each_point</a>(lscopy, translate_function&lt;point_2d&gt;);
std::cout &lt;&lt; <span class="stringliteral">"modified line: "</span> &lt;&lt; <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">boost::geometry::dsv</a>(lscopy) &lt;&lt; std::endl;
}
<span class="comment">// Lines can be clipped using a clipping box. Clipped lines are added to the output iterator</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(<a name="a14"></a><a class="code" href="namespaceboost_1_1geometry.html#40d187c066f4ce55e4702be61ddfd823">point_2d</a>(1.5, 1.5), <a class="code" href="namespaceboost_1_1geometry.html#40d187c066f4ce55e4702be61ddfd823">point_2d</a>(4.5, 2.5));
std::vector&lt;linestring_2d&gt; clipped;
intersection_inserter&lt;linestring_2d&gt; (cb, ls, std::back_inserter(clipped));
<span class="comment">// Also possible: clip-output to a vector of vectors</span>
std::vector&lt;std::vector&lt;point_2d&gt; &gt; vector_out;
intersection_inserter&lt;std::vector&lt;point_2d&gt; &gt;(cb, ls, std::back_inserter(vector_out));
std::cout &lt;&lt; <span class="stringliteral">"clipped output as vector:"</span> &lt;&lt; std::endl;
<span class="keywordflow">for</span> (std::vector&lt;std::vector&lt;point_2d&gt; &gt;::const_iterator it
= vector_out.begin(); it != vector_out.end(); ++it)
{
std::cout &lt;&lt; <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">boost::geometry::dsv</a>(*it) &lt;&lt; std::endl;
}
<span class="comment">// Calculate the convex hull of the linestring</span>
<a name="_a15"></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> hull;
<a name="a16"></a><a class="code" href="namespaceboost_1_1geometry.html#dc3a1eff51c809466fdfeb14a820be8a">convex_hull</a>(ls, hull);
std::cout &lt;&lt; <span class="stringliteral">"Convex hull:"</span> &lt;&lt; <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">boost::geometry::dsv</a>(hull) &lt;&lt; std::endl;
<span class="comment">// All the above assumed 2D Cartesian linestrings. 3D is possible as well</span>
<span class="comment">// Let's define a 3D point ourselves, this time using 'float'</span>
<span class="keyword">typedef</span> <a name="_a17"></a><a class="code" href="classboost_1_1geometry_1_1point.html" title="Basic point class, having coordinates defined in a neutral way.">point&lt;float, 3, cs::cartesian&gt;</a> <a name="_a18"></a><a class="code" href="structboost_1_1geometry_1_1point__type.html" title="Meta-function which defines point type of any geometry.">point_type</a>;
<span class="keyword">typedef</span> <a class="code" href="classboost_1_1geometry_1_1linestring.html" title="A linestring (named so by OGC) is a collection (default a vector) of points.">linestring&lt;point_type&gt;</a> line_type;
line_type line3d;
line3d.push_back(make&lt;point_type&gt;(1,2,3));
line3d.push_back(make&lt;point_type&gt;(4,5,6));
line3d.push_back(make&lt;point_type&gt;(7,8,9));
<span class="comment">// Not all algorithms work on 3d lines. For example convex hull does NOT.</span>
<span class="comment">// But, for example, length, distance, simplify, envelope and stream do.</span>
std::cout &lt;&lt; <span class="stringliteral">"3D: length: "</span> &lt;&lt; <a class="code" href="group__length.html#g1537537131cd91037cf3ad9fd80d50f1" title="Calculate length of a geometry.">length</a>(line3d) &lt;&lt; <span class="stringliteral">" line: "</span> &lt;&lt; <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">boost::geometry::dsv</a>(line3d) &lt;&lt; std::endl;
<span class="comment">// With DSV you can also use other delimiters, e.g. JSON style</span>
std::cout &lt;&lt; <span class="stringliteral">"JSON: "</span>
&lt;&lt; <a class="code" href="group__utility.html#g62cc5db4d3bb1147591298b3500f8f1a" title="Main DSV-streaming function.">boost::geometry::dsv</a>(ls, <span class="stringliteral">", "</span>, <span class="stringliteral">"["</span>, <span class="stringliteral">"]"</span>, <span class="stringliteral">", "</span>, <span class="stringliteral">"[ "</span>, <span class="stringliteral">" ]"</span>)
&lt;&lt; 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 <20> 1995-2009 Barend Gehrels, Geodan, Amsterdam<br>
Copyright <20> 2008-2009 Bruno Lalande, Paris<br>
Copyright <20> 2009 Mateusz Loskot, Cadcorp, London<br>
</small>
</td>
</tr>
</tbody>
</table>
<address style="text-align: right;"><small>
Documentation is generated by&nbsp;<a href="http://www.doxygen.org/index.html">Doxygen</a>
</small></address>
</body>
</html>