Merge branch 'develop' of https://github.com/boostorg/geometry into feature/set_ops_pointlike_linear

This commit is contained in:
Menelaos Karavelas
2015-04-23 10:13:54 +03:00
227 changed files with 5139 additions and 2016 deletions

View File

@@ -35,22 +35,42 @@ __boost_geometry__ library has been successfully tested with the following
compilers:
* __msvc__ (including Express Editions)
* 14.0 (__msvc__ 14 CTP) [/reported by develop report on March, 2015]
* 12.0 (__msvc__ 2013) [/reported by develop report on March, 2015]
* 11.0 (__msvc__ 2012) [/reported by develop report on March, 2015]
* 10.0 (__msvc__ 2010) [/reported by Trunk report May 8, 2011]
* 9.0 (__msvc__ 2008) [/reported by Trunk report May 8, 2011]
* 8.0 (__msvc__ 2005) [/reported by Trunk report May 8, 2011]
* gcc
* gcc 5.0.0 [/reported by develop report on March, 2015]
* gcc 4.9.2 [/reported by develop report on March, 2015]
* gcc 4.9.0 [/reported by develop report on March, 2015]
* gcc 4.8.4 [/reported by develop report on March, 2015]
* gcc 4.8.1 [/reported by develop report on March, 2015]
* gcc 4.8.0 [/reported by develop report on March, 2015]
* gcc 4.7.3 [/reported by develop report on March, 2015]
* gcc 4.7.2 [/reported by develop report on March, 2015]
* gcc 4.7.0 [/reported by Trunk report February 12, 2012]
* gcc 4.6.4 [/reported by develop report on March, 2015]
* gcc 4.6.2 [/reported by Trunk report February 12, 2012]
* gcc 4.6.1 [/reported by Trunk report May 8, 2011]
* gcc 4.6.0 [/reported by Trunk report May 8, 2011]
* gcc 4.5.3 [/reported by develop report on March, 2015]
* gcc 4.5.2 [/reported by Trunk report May 8, 2011]
* gcc 4.4.7 [/reported by develop report on March, 2015]
* gcc 4.4.0 [/reported by Trunk report May 8, 2011]
* gcc 4.3.4 [/reported by Trunk report March 26, 2011]
* gcc 4.2.1 [/reported by Trunk report May 8, 2011]
* gcc 3.4.6 [/reported by Trunk report March 26, 2011]
* clang
* clang 3.6 [/reported by develop report on March, 2015]
* clang 3.5 [/reported by develop report on March, 2015]
* clang 3.4 [/reported by develop report on March, 2015]
* clang 3.3 [/reported by mloskot on October, 2013]
* clang 3.2 [/reported by Trunk report March 26, 2011]
* clang 3.1 [/reported by develop report on March, 2015]
* clang 3.0 [/reported by develop report on March, 2015]
* clang 2.9 [/reported by develop report on March, 2015]
* darwin
* darwin 4.0.1 [/reported by Trunk report March 26, 2011]
* darwin 4.4 [/reported by Trunk report March 26, 2011]

View File

@@ -89,6 +89,7 @@ ALIASES = qbk{1}="\xmlonly <qbk>\1</qbk> \endxmlonly" \
param_x="First coordinate (usually x-coordinate)" \
param_y="Second coordinate (usually y-coordinate)" \
param_z="Third coordinate (usually z-coordinate)" \
constructor_default_no_init="Default constructor, no initialization" \
constructor_default{1}="Default constructor, creating an empty \1" \
constructor_begin_end{1}="Constructor with begin and end, filling the \1" \
constructor_initializer_list{1}="Constructor taking std::initializer_list, filling the \1" \
@@ -200,13 +201,6 @@ INPUT = . .. ../../../../boost/geometry/core \
../../../../boost/geometry/iterators \
../../../../boost/geometry/io/wkt \
../../../../boost/geometry/io/svg \
../../../../boost/geometry/multi/algorithms \
../../../../boost/geometry/multi/algorithms/detail \
../../../../boost/geometry/multi/core \
../../../../boost/geometry/multi/geometries \
../../../../boost/geometry/multi/geometries/register \
../../../../boost/geometry/multi/geometries/concepts \
../../../../boost/geometry/multi/strategies/cartesian \
../../../../boost/geometry/policies \
../../../../boost/geometry/policies/relate \
../../../../boost/geometry/strategies \

View File

@@ -118,9 +118,6 @@ For users using only Cartesian points, with floating point coordinates (double),
etc. Using this headerfile the library seems to be a non-template library, so it is convenient for users that
are not so into the template world.
For users using multi-geometries:
- \#include <boost/geometry/multi/multi.hpp>
\section advanced_includes Advanced includes
This section is for users who have their own geometries and want to use algorithms from the Boost.Geometry.

View File

@@ -15,8 +15,6 @@ OBSOLETE
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/multi/multi.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#include <boost/geometry/io/svg/write_svg_multi.hpp>

View File

@@ -82,7 +82,17 @@
[import src/examples/core/tag.cpp]
[import src/examples/core/tag_cast.cpp]
[import src/examples/geometries/box.cpp]
[import src/examples/geometries/linestring.cpp]
[import src/examples/geometries/multi_linestring.cpp]
[import src/examples/geometries/multi_point.cpp]
[import src/examples/geometries/multi_polygon.cpp]
[import src/examples/geometries/point_xy.cpp]
[import src/examples/geometries/point.cpp]
[import src/examples/geometries/polygon.cpp]
[import src/examples/geometries/ring.cpp]
[import src/examples/geometries/segment.cpp]
[import src/examples/geometries/adapted/c_array.cpp]
[import src/examples/geometries/adapted/boost_array.cpp]
[import src/examples/geometries/adapted/boost_fusion.cpp]

View File

@@ -56,8 +56,10 @@ The examples of structures of trees created by use of different algorithms and e
[[*100k knn queries*] [6.37s] [2.09s] [0.64s] [0.52s]]
]
The configuration of the machine used for testing was: /Intel(R) Core(TM) i7 870 @ 2.93GHz, 8GB RAM, MS Windows 7 x64/.
The code was compiled with optimization for speed (`O2`).
The performance of the R-tree for different values of Max parameter and Min=0.5*Max is presented in the table below.
The configuration of the machine used for testing is: /Intel(R) Core(TM) i7 870 @ 2.93GHz, 8GB RAM, MS Windows 7 x64/.
In the two upper figures you can see the performance of the __rtree__ storing random, relatively small, non-overlapping, 2d boxes.
In the lower ones, the performance of the __rtree__ also storing random, 2d boxes, but this time quite big and possibly overlapping.
As you can see, the __rtree__ performance is different in both cases.

View File

@@ -0,0 +1,16 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
Copyright (c) 2009-2012 Bruno Lalande, Paris, France.
Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================/]
[heading Examples]
[box]
[box_output]

View File

@@ -0,0 +1,16 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
Copyright (c) 2009-2012 Bruno Lalande, Paris, France.
Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================/]
[heading Examples]
[linestring]
[linestring_output]

View File

@@ -0,0 +1,16 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
Copyright (c) 2009-2012 Bruno Lalande, Paris, France.
Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================/]
[heading Examples]
[multi_linestring]
[multi_linestring_output]

View File

@@ -0,0 +1,16 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
Copyright (c) 2009-2012 Bruno Lalande, Paris, France.
Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================/]
[heading Examples]
[multi_point]
[multi_point_output]

View File

@@ -0,0 +1,16 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
Copyright (c) 2009-2012 Bruno Lalande, Paris, France.
Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================/]
[heading Examples]
[multi_polygon]
[multi_polygon_output]

View File

@@ -0,0 +1,18 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
Copyright (c) 2009-2012 Bruno Lalande, Paris, France.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================/]
[heading Examples]
[point_xy]
[point_xy_output]
[include reference/geometries/point_assign_warning.qbk]

View File

@@ -0,0 +1,16 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
Copyright (c) 2009-2012 Bruno Lalande, Paris, France.
Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================/]
[heading Examples]
[polygon]
[polygon_output]

View File

@@ -0,0 +1,16 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
Copyright (c) 2009-2012 Bruno Lalande, Paris, France.
Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================/]
[heading Examples]
[ring]
[ring_output]

View File

@@ -0,0 +1,16 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
Copyright (c) 2009-2012 Bruno Lalande, Paris, France.
Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================/]
[heading Examples]
[segment]
[segment_output]

View File

@@ -18,6 +18,23 @@
[section:release_notes Release Notes]
[/=================]
[heading Boost 1.59]
[/=================]
[*Additional functionality]
* Added rtree const_iterator, begin(), end() and the support for Boost.Range.
* The support for C++11 `std::initializer_list` in geometries models.
[*Improvements]
* Upgraded rtree const_query_iterator category to ForwardIterator.
[*Solved tickets]
* [@https://svn.boost.org/trac/boost/ticket/11113 11113] Support easy enumeration of all elements with BOOST_FOREACH
[/=================]
[heading Boost 1.58]
[/=================]
@@ -37,22 +54,30 @@
[*Solved tickets]
* [@https://svn.boost.org/trac/boost/ticket/8379 8379] Invalid comparison of the result of determinant
* [@https://svn.boost.org/trac/boost/ticket/10108 10108] Error in overlay operations in specific cases where geometries touch at one point
* [@https://svn.boost.org/trac/boost/ticket/10201 10201] Suggestion to use different function to compare coordinates [wontfix]
* [@https://svn.boost.org/trac/boost/ticket/10467 10467] Template parameter name coliding with B0 macro name defined in termios.h
* [@https://svn.boost.org/trac/boost/ticket/10640 10640] Invalid result of buffer() for CCW Polygons.
* [@https://svn.boost.org/trac/boost/ticket/10666 10666] MSVC compiler warning C4127: conditional expression is constant
* [@https://svn.boost.org/trac/boost/ticket/10747 10747] Error in rescaling causing errors in areal/areal set operations
* [@https://svn.boost.org/trac/boost/ticket/10770 10770] Buffer fails for large distances, or rough round joins, where concavities where not intersected properly
* [@https://svn.boost.org/trac/boost/ticket/10658 10658] sym_difference yields bad result for int polygons
* [@https://svn.boost.org/trac/boost/ticket/10835 10835] Difference of multilinestring and polygon yields wrong result
* [@https://svn.boost.org/trac/boost/ticket/10861 10861] Rtree failing to compile for Value being a pair or a tuple containing pointer to Geometry and the default equal_to<> used
* [@https://svn.boost.org/trac/boost/ticket/10863 10863] Template parameter name coliding with B0 macro name defined in termios.h (duplicate of 10467)
* [@https://svn.boost.org/trac/boost/ticket/10887 10887] Invalid result of within() and relate() for Linear/MultiPolygon
* [@https://svn.boost.org/trac/boost/ticket/10890 10890] Invalid result of disjoint() for Point/Segment.
* [@https://svn.boost.org/trac/boost/ticket/10904 10904] Invalid calculation of most significant Dimension of a segment in relate_cartesian_segments strategy
* [@https://svn.boost.org/trac/boost/ticket/10912 10912] Invalid result of within() and relate() for Areal/Areal
* [@https://svn.boost.org/trac/boost/ticket/10951 10951] Tests failing on windows with intel compiler due to lack of /bigobj flag.
* [@https://svn.boost.org/trac/boost/ticket/10957 10957] Assertion failure and invalid results of various relational operations.
* [@https://svn.boost.org/trac/boost/ticket/10958 10958] Invalid results of disjoint() L/L and L/A.
* [@https://svn.boost.org/trac/boost/ticket/10959 10959] Assertion failure in get_turns() used with no_rescale_policy.
* [@https://svn.boost.org/trac/boost/ticket/10960 10960] Invalid result of get_turns() for L/A, missing turn.
* [@https://svn.boost.org/trac/boost/ticket/10961 10961] Invalid result of get_turns() for L/A, invalid turn for a Linear spike.
* [@https://svn.boost.org/trac/boost/ticket/11112 11112] Compilation failure on Solaris due to a CS name clash (used for a macro on this platform)
* [@https://svn.boost.org/trac/boost/ticket/11121 11121] Invalid result of difference() for integral coordinates
[*Bugfixes]
@@ -68,6 +93,9 @@
* Bug in buffers for interior rings with large negative buffer distances
* Bug in closing_iterator not working properly when the input range is empty
* Bug in is_simple, not handling properly closed simple linestrings within multilinestrings
* Bug in rtree constructors taking a pair of Iterators or a Range (packing algorithm), the use of reference to destroyed temporary when Iterator's reference is not true reference, e.g. for some of the Range Adaptors. It also affects distance() and comparable_distance(). This bug may cause unexpected behavior of the rtree or distance() algorithm, e.g. an assertion failure or a SEGFAULT.
* Bug in rtree count() member function, the use of reference to destroyed temporary when object of type convertible but not the same as value_type or indexable_type is passed. If this happens, wrong result may be returned, in most cases 0.
* Bugs related to the handling of Ranges, preventing compilation of Geometries using non-Container Ranges in some algorithms (thanks to Samuel Debionne)
[/=================]
[heading Boost 1.57]

View File

@@ -8,6 +8,6 @@ xml=../../../../doxy/doxygen_output/xml/structboost_1_1geometry_1_1closeable__vi
start_include=boost/geometry/
convenience_header_path=../../../../../../../boost/geometry/
convenience_headers=geometry.hpp,geometries/geometries.hpp,multi/multi.hpp
convenience_headers=geometry.hpp,geometries/geometries.hpp
skip_namespace=boost::geometry::

View File

@@ -973,7 +973,11 @@ void quickbook_template_parameter_list_alt(std::vector<parameter> const& paramet
if ( !p.default_value.empty() )
{
out << " = ";
inline_str_with_links(p.default_value, out);
// don't display default values from details
if ( p.default_value.find("detail") != std::string::npos )
out << "/default/";
else
inline_str_with_links(p.default_value, out);
}
first = false;
@@ -996,13 +1000,20 @@ void quickbook_synopsis_alt(function const& f, std::ostream& out)
offset += f.name.size();
break;
case function_member :
inline_str_with_links(f.return_type, out);
out << " `" << f.name << "`";
offset += f.return_type_without_links.size() + 1 + f.name.size();
break;
case function_free :
inline_str_with_links(f.definition, out);
offset += f.definition.size();
// don't display return types from details
if ( f.return_type.find("detail") != std::string::npos )
{
out << "/unspecified/";
offset += 11;
}
else
{
inline_str_with_links(f.return_type, out);
offset += f.return_type_without_links.size();
}
out << " `" << f.name << "`";
offset += 1 + f.name.size();
break;
case function_define :
out << "`#define " << f.name << "`";
@@ -1036,7 +1047,11 @@ void quickbook_synopsis_alt(function const& f, std::ostream& out)
if ( !p.default_value.empty() )
{
out << " = ";
inline_str_with_links(p.default_value, out);
// don't display default values from details
if ( p.default_value.find("detail") != std::string::npos )
out << "/default/";
else
inline_str_with_links(p.default_value, out);
}
first = false;
}
@@ -1076,20 +1091,24 @@ void quickbook_synopsis_alt(class_or_struct const& cos, configuration const& con
if (! cos.base_classes.empty())
{
out << "` : ";
bool first = true;
BOOST_FOREACH(base_class const& bc, cos.base_classes)
{
if (! first)
{
// don't display base classes from details
if ( bc.name.find("detail") != std::string::npos )
continue;
if (first)
out << "` : ";
else
out << std::endl << " , ";
}
out << output_if_different(bc.derivation, "private")
<< output_if_different(bc.virtuality, "non-virtual")
<< namespace_skipped(bc.name, config);
first = false;
}
out << "`" << std::endl;
if (!first)
out << "`" << std::endl;
}
out << "`{`" << std::endl

View File

@@ -1,8 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Tool reporting Implementation Support Status in QBK or plain text format
// Copyright (c) 2011-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2011-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2011-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -48,26 +48,6 @@
#include <boost/geometry/algorithms/transform.hpp>
#include <boost/geometry/algorithms/unique.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#include <boost/geometry/multi/algorithms/append.hpp>
#include <boost/geometry/multi/algorithms/area.hpp>
#include <boost/geometry/multi/algorithms/centroid.hpp>
#include <boost/geometry/multi/algorithms/clear.hpp>
#include <boost/geometry/multi/algorithms/convert.hpp>
#include <boost/geometry/multi/algorithms/correct.hpp>
#include <boost/geometry/multi/algorithms/covered_by.hpp>
#include <boost/geometry/multi/algorithms/distance.hpp>
#include <boost/geometry/multi/algorithms/envelope.hpp>
#include <boost/geometry/multi/algorithms/equals.hpp>
#include <boost/geometry/multi/algorithms/for_each.hpp>
#include <boost/geometry/multi/algorithms/length.hpp>
#include <boost/geometry/multi/algorithms/num_geometries.hpp>
#include <boost/geometry/multi/algorithms/num_interior_rings.hpp>
#include <boost/geometry/multi/algorithms/num_points.hpp>
#include <boost/geometry/multi/algorithms/perimeter.hpp>
#include <boost/geometry/multi/algorithms/reverse.hpp>
#include <boost/geometry/multi/algorithms/simplify.hpp>
#include <boost/geometry/multi/algorithms/transform.hpp>
#include <boost/geometry/multi/algorithms/unique.hpp>
#include <boost/geometry/strategies/strategies.hpp>
#include "text_outputter.hpp"
@@ -103,6 +83,11 @@ typedef boost::mpl::vector<
struct algorithm: boost::geometry::dispatch::algorithm<G> \
{};
#define DECLARE_UNARY_ALGORITHM_WITH_BOOLEAN(algorithm) \
template <typename G> \
struct algorithm: boost::geometry::dispatch::algorithm<G,false> \
{};
#define DECLARE_BINARY_ALGORITHM(algorithm) \
template <typename G1, typename G2> \
struct algorithm: boost::geometry::dispatch::algorithm<G1, G2> \
@@ -129,7 +114,7 @@ DECLARE_UNARY_ALGORITHM(is_valid)
DECLARE_UNARY_ALGORITHM(length)
DECLARE_UNARY_ALGORITHM(num_geometries)
DECLARE_UNARY_ALGORITHM(num_interior_rings)
DECLARE_UNARY_ALGORITHM(num_points)
DECLARE_UNARY_ALGORITHM_WITH_BOOLEAN(num_points)
DECLARE_UNARY_ALGORITHM(num_segments)
DECLARE_BINARY_ALGORITHM(overlaps)
DECLARE_UNARY_ALGORITHM(perimeter)

View File

@@ -13,7 +13,16 @@ project boost-geometry-doc-src-example-geometries
: # requirements
;
exe box : box.cpp ;
exe linestring : linestring.cpp ;
exe point : point.cpp ;
exe point_xy : point_xy.cpp ;
exe polygon : polygon.cpp ;
exe multi_linestring : multi_linestring.cpp ;
exe multi_point : multi_point.cpp ;
exe multi_polygon : multi_polygon.cpp ;
exe ring : ring.cpp ;
exe segment : segment.cpp ;
build-project adapted ;
build-project register ;

View File

@@ -0,0 +1,58 @@
// Boost.Geometry
// QuickBook Example
// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//[box
//` Declaration and use of the Boost.Geometry model::box, modelling the Box Concept
#include <iostream>
#include <boost/geometry.hpp>
namespace bg = boost::geometry;
int main()
{
typedef bg::model::point<double, 2, bg::cs::cartesian> point_t;
typedef bg::model::box<point_t> box_t;
box_t box1; /*< Default-construct a box. >*/
box_t box2(point_t(0.0, 0.0), point_t(5.0, 5.0)); /*< Construct, assigning min and max corner point. >*/
#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
box_t box3{{0.0, 0.0}, {5.0, 5.0}}; /*< Construct, using C++11 unified initialization syntax. >*/
#endif
bg::set<bg::min_corner, 0>(box1, 1.0); /*< Set a coordinate, generic. >*/
bg::set<bg::min_corner, 1>(box1, 2.0);
box1.max_corner().set<0>(3.0); /*< Set a coordinate, class-specific ([*Note]: prefer `bg::set()`). >*/
box1.max_corner().set<1>(4.0);
double min_x = bg::get<bg::min_corner, 0>(box1); /*< Get a coordinate, generic. >*/
double min_y = bg::get<bg::min_corner, 1>(box1);
double max_x = box1.max_corner().get<0>(); /*< Get a coordinate, class-specific ([*Note]: prefer `bg::get()`). >*/
double max_y = box1.max_corner().get<1>();
std::cout << min_x << ", " << min_y << ", " << max_x << ", " << max_y << std::endl;
return 0;
}
//]
//[box_output
/*`
Output:
[pre
1, 2, 3, 4
]
*/
//]

View File

@@ -0,0 +1,55 @@
// Boost.Geometry
// QuickBook Example
// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//[linestring
//` Declaration and use of the Boost.Geometry model::linestring, modelling the Linestring Concept
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
namespace bg = boost::geometry;
int main()
{
typedef bg::model::point<double, 2, bg::cs::cartesian> point_t;
typedef bg::model::linestring<point_t> linestring_t;
linestring_t ls1; /*< Default-construct a linestring. >*/
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) \
&& !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
linestring_t ls2{{0.0, 0.0}, {1.0, 0.0}, {1.0, 2.0}}; /*< Construct a linestring containing three points, using C++11 unified initialization syntax. >*/
#endif
bg::append(ls1, point_t(0.0, 0.0)); /*< Append point. >*/
bg::append(ls1, point_t(1.0, 0.0));
bg::append(ls1, point_t(1.0, 2.0));
double l = bg::length(ls1);
std::cout << l << std::endl;
return 0;
}
//]
//[linestring_output
/*`
Output:
[pre
3
]
*/
//]

View File

@@ -0,0 +1,62 @@
// Boost.Geometry
// QuickBook Example
// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//[multi_linestring
//` Declaration and use of the Boost.Geometry model::multi_linestring, modelling the MultiLinestring Concept
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
namespace bg = boost::geometry;
int main()
{
typedef bg::model::point<double, 2, bg::cs::cartesian> point_t;
typedef bg::model::linestring<point_t> linestring_t;
typedef bg::model::multi_linestring<linestring_t> mlinestring_t;
mlinestring_t mls1; /*< Default-construct a multi_linestring. >*/
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) \
&& !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
mlinestring_t mls2{{{0.0, 0.0}, {0.0, 1.0}, {2.0, 1.0}},
{{1.0, 0.0}, {2.0, 0.0}}}; /*< Construct a multi_linestring containing two linestrings, using C++11 unified initialization syntax. >*/
#endif
mls1.resize(2); /*< Resize a multi_linestring, store two linestrings. >*/
bg::append(mls1[0], point_t(0.0, 0.0)); /*< Append point to the first linestring. >*/
bg::append(mls1[0], point_t(0.0, 1.0));
bg::append(mls1[0], point_t(2.0, 1.0));
bg::append(mls1[1], point_t(1.0, 0.0)); /*< Append point to the second linestring. >*/
bg::append(mls1[1], point_t(2.0, 0.0));
double l = bg::length(mls1);
std::cout << l << std::endl;
return 0;
}
//]
//[multi_linestring_output
/*`
Output:
[pre
4
]
*/
//]

View File

@@ -0,0 +1,55 @@
// Boost.Geometry
// QuickBook Example
// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//[multi_point
//` Declaration and use of the Boost.Geometry model::multi_point, modelling the MultiPoint Concept
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
namespace bg = boost::geometry;
int main()
{
typedef bg::model::point<double, 2, bg::cs::cartesian> point_t;
typedef bg::model::multi_point<point_t> mpoint_t;
mpoint_t mpt1; /*< Default-construct a multi_point. >*/
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) \
&& !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
mpoint_t mpt2{{{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}}}; /*< Construct a multi_point containing three points, using C++11 unified initialization syntax. >*/
#endif
bg::append(mpt1, point_t(0.0, 0.0)); /*< Append point to the multi_point. >*/
bg::append(mpt1, point_t(1.0, 1.0));
bg::append(mpt1, point_t(2.0, 2.0));
std::size_t count = bg::num_points(mpt1);
std::cout << count << std::endl;
return 0;
}
//]
//[multi_point_output
/*`
Output:
[pre
3
]
*/
//]

View File

@@ -0,0 +1,75 @@
// Boost.Geometry
// QuickBook Example
// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//[multi_polygon
//` Declaration and use of the Boost.Geometry model::multi_polygon, modelling the MultiPolygon Concept
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
namespace bg = boost::geometry;
int main()
{
typedef bg::model::point<double, 2, bg::cs::cartesian> point_t;
typedef bg::model::polygon<point_t> polygon_t; /*< Default parameters, clockwise, closed polygon. >*/
typedef bg::model::multi_polygon<polygon_t> mpolygon_t; /*< Clockwise, closed multi_polygon. >*/
mpolygon_t mpoly1; /*< Default-construct a multi_polygon. >*/
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) \
&& !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
mpolygon_t mpoly2{{{{0.0, 0.0}, {0.0, 5.0}, {5.0, 5.0}, {5.0, 0.0}, {0.0, 0.0}},
{{1.0, 1.0}, {4.0, 1.0}, {4.0, 4.0}, {1.0, 4.0}, {1.0, 1.0}}},
{{{5.0, 5.0}, {5.0, 6.0}, {6.0, 6.0}, {6.0, 5.0}, {5.0, 5.0}}}}; /*< Construct a multi_polygon containing two polygons, using C++11 unified initialization syntax. >*/
#endif
mpoly1.resize(2); /*< Resize a multi_polygon, store two polygons. >*/
bg::append(mpoly1[0].outer(), point_t(0.0, 0.0)); /*< Append point to the exterior ring of the first polygon. >*/
bg::append(mpoly1[0].outer(), point_t(0.0, 5.0));
bg::append(mpoly1[0].outer(), point_t(5.0, 5.0));
bg::append(mpoly1[0].outer(), point_t(5.0, 0.0));
bg::append(mpoly1[0].outer(), point_t(0.0, 0.0));
mpoly1[0].inners().resize(1); /*< Resize a container of interior rings of the first polygon. >*/
bg::append(mpoly1[0].inners()[0], point_t(1.0, 1.0)); /*< Append point to the interior ring of the first polygon. >*/
bg::append(mpoly1[0].inners()[0], point_t(4.0, 1.0));
bg::append(mpoly1[0].inners()[0], point_t(4.0, 4.0));
bg::append(mpoly1[0].inners()[0], point_t(1.0, 4.0));
bg::append(mpoly1[0].inners()[0], point_t(1.0, 1.0));
bg::append(mpoly1[1].outer(), point_t(5.0, 5.0)); /*< Append point to the exterior ring of the second polygon. >*/
bg::append(mpoly1[1].outer(), point_t(5.0, 6.0));
bg::append(mpoly1[1].outer(), point_t(6.0, 6.0));
bg::append(mpoly1[1].outer(), point_t(6.0, 5.0));
bg::append(mpoly1[1].outer(), point_t(5.0, 5.0));
double a = bg::area(mpoly1);
std::cout << a << std::endl;
return 0;
}
//]
//[multi_polygon_output
/*`
Output:
[pre
17
]
*/
//]

View File

@@ -19,11 +19,12 @@ int main()
{
bg::model::point<double, 2, bg::cs::cartesian> point1;
bg::model::point<double, 3, bg::cs::cartesian> point2(1.0, 2.0, 3.0); /*< Construct, assigning three coordinates >*/
point1.set<0>(1.0); /*< Set a coordinate. [*Note]: prefer using `bg::set<0>(point1, 1.0);` >*/
point1.set<1>(2.0);
double x = point1.get<0>(); /*< Get a coordinate. [*Note]: prefer using `x = bg::get<0>(point1);` >*/
double y = point1.get<1>();
bg::set<0>(point1, 1.0); /*< Set a coordinate, generic. >*/
point1.set<1>(2.0); /*< Set a coordinate, class-specific ([*Note]: prefer `bg::set()`). >*/
double x = bg::get<0>(point1); /*< Get a coordinate, generic. >*/
double y = point1.get<1>(); /*< Get a coordinate, class-specific ([*Note]: prefer `bg::get()`). >*/
std::cout << x << ", " << y << std::endl;
return 0;

View File

@@ -0,0 +1,44 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// QuickBook Example
// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//[point_xy
//` Declaration and use of the Boost.Geometry model::d2::point_xy, modelling the Point Concept
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
namespace bg = boost::geometry;
int main()
{
bg::model::d2::point_xy<double> point1;
bg::model::d2::point_xy<double> point2(1.0, 2.0); /*< Construct, assigning coordinates. >*/
bg::set<0>(point1, 1.0); /*< Set a coordinate, generic. >*/
point1.y(2.0); /*< Set a coordinate, class-specific ([*Note]: prefer `bg::set()`). >*/
double x = bg::get<0>(point1); /*< Get a coordinate, generic. >*/
double y = point1.y(); /*< Get a coordinate, class-specific ([*Note]: prefer `bg::get()`). >*/
std::cout << x << ", " << y << std::endl;
return 0;
}
//]
//[point_xy_output
/*`
Output:
[pre
1, 2
]
*/
//]

View File

@@ -0,0 +1,65 @@
// Boost.Geometry
// QuickBook Example
// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//[polygon
//` Declaration and use of the Boost.Geometry model::polygon, modelling the Polygon Concept
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
namespace bg = boost::geometry;
int main()
{
typedef bg::model::point<double, 2, bg::cs::cartesian> point_t;
typedef bg::model::polygon<point_t> polygon_t; /*< Default parameters, clockwise, closed polygon. >*/
polygon_t poly1; /*< Default-construct a polygon. >*/
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) \
&& !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
polygon_t polygon2{{{0.0, 0.0}, {0.0, 5.0}, {5.0, 5.0}, {5.0, 0.0}, {0.0, 0.0}},
{{1.0, 1.0}, {4.0, 1.0}, {4.0, 4.0}, {1.0, 4.0}, {1.0, 1.0}}}; /*< Construct a polygon containing an exterior and interior ring, using C++11 unified initialization syntax. >*/
#endif
bg::append(poly1.outer(), point_t(0.0, 0.0)); /*< Append point to the exterior ring. >*/
bg::append(poly1.outer(), point_t(0.0, 5.0));
bg::append(poly1.outer(), point_t(5.0, 5.0));
bg::append(poly1.outer(), point_t(5.0, 0.0));
bg::append(poly1.outer(), point_t(0.0, 0.0));
poly1.inners().resize(1); /*< Resize a container of interior rings. >*/
bg::append(poly1.inners()[0], point_t(1.0, 1.0)); /*< Append point to the interior ring. >*/
bg::append(poly1.inners()[0], point_t(4.0, 1.0));
bg::append(poly1.inners()[0], point_t(4.0, 4.0));
bg::append(poly1.inners()[0], point_t(1.0, 4.0));
bg::append(poly1.inners()[0], point_t(1.0, 1.0));
double a = bg::area(poly1);
std::cout << a << std::endl;
return 0;
}
//]
//[polygon_output
/*`
Output:
[pre
16
]
*/
//]

View File

@@ -0,0 +1,57 @@
// Boost.Geometry
// QuickBook Example
// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//[ring
//` Declaration and use of the Boost.Geometry model::ring, modelling the Ring Concept
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
namespace bg = boost::geometry;
int main()
{
typedef bg::model::point<double, 2, bg::cs::cartesian> point_t;
typedef bg::model::ring<point_t> ring_t; /*< Default parameters, clockwise, closed ring. >*/
ring_t ring1; /*< Default-construct a ring. >*/
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) \
&& !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
ring_t ring2{{0.0, 0.0}, {0.0, 5.0}, {5.0, 5.0}, {5.0, 0.0}, {0.0, 0.0}}; /*< Construct a ring containing four points plus one closing point, using C++11 unified initialization syntax. >*/
#endif
bg::append(ring1, point_t(0.0, 0.0)); /*< Append point. >*/
bg::append(ring1, point_t(0.0, 5.0));
bg::append(ring1, point_t(5.0, 5.0));
bg::append(ring1, point_t(5.0, 0.0));
bg::append(ring1, point_t(0.0, 0.0));
double a = bg::area(ring1);
std::cout << a << std::endl;
return 0;
}
//]
//[ring_output
/*`
Output:
[pre
25
]
*/
//]

View File

@@ -0,0 +1,59 @@
// Boost.Geometry
// QuickBook Example
// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//[segment
//` Declaration and use of the Boost.Geometry model::segment, modelling the Segment Concept
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
namespace bg = boost::geometry;
int main()
{
typedef bg::model::point<double, 2, bg::cs::cartesian> point_t;
typedef bg::model::segment<point_t> segment_t;
segment_t seg1; /*< Default-construct a segment. >*/
segment_t seg2(point_t(0.0, 0.0), point_t(5.0, 5.0)); /*< Construct, assigning the first and the second point. >*/
#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
segment_t seg3{{0.0, 0.0}, {5.0, 5.0}}; /*< Construct, using C++11 unified initialization syntax. >*/
#endif
bg::set<0, 0>(seg1, 1.0); /*< Set a coordinate. >*/
bg::set<0, 1>(seg1, 2.0);
bg::set<1, 0>(seg1, 3.0);
bg::set<1, 1>(seg1, 4.0);
double x0 = bg::get<0, 0>(seg1); /*< Get a coordinate. >*/
double y0 = bg::get<0, 1>(seg1);
double x1 = bg::get<1, 0>(seg1);
double y1 = bg::get<1, 1>(seg1);
std::cout << x0 << ", " << y0 << ", " << x1 << ", " << y1 << std::endl;
return 0;
}
//]
//[segment_output
/*`
Output:
[pre
1, 2, 3, 4
]
*/
//]

View File

@@ -18,8 +18,6 @@
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/geometries/register/linestring.hpp>
// To register the 'geographic' distance function to calculate distance over the earth:
#include <boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp>
#include <boost/geometry/extensions/algorithms/parse.hpp>
// Define a GPS point with coordinates in latitude/longitude and some additional values

View File

@@ -14,10 +14,6 @@
#include <boost/geometry/geometry.hpp>
#ifdef OPTIONALLY_ELLIPSOIDAL // see below
#include <boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp>
#endif
// 1: declare a coordinate system. For example for Mars
// Like for the Earth, we let the use choose between degrees or radians
// (Unfortunately, in real life Mars has two coordinate systems:
@@ -54,7 +50,7 @@ namespace boost { namespace geometry { namespace strategy { namespace distance {
{
template <typename Point1, typename Point2>
struct default_strategy<point_tag, Point1, Point2, martian_tag, martian_tag>
struct default_strategy<point_tag, point_tag, Point1, Point2, martian_tag, martian_tag>
{
typedef haversine<double> type;
};
@@ -98,7 +94,7 @@ int main()
// giving 834.444 km
d = boost::geometry::distance(viking1, pathfinder,
boost::geometry::strategy::distance::andoyer<mars_point>
(boost::geometry::detail::ellipsoid<double>(3396.2, 3376.2)));
(boost::geometry::srs::spheroid<double>(3396.2, 3376.2)));
std::cout << "Ellipsoidal distance: " << d << " km" << std::endl;
#endif

View File

@@ -90,7 +90,7 @@ namespace boost { namespace geometry { namespace strategy { namespace distance {
};
template <>
struct default_strategy<point_tag, point1, point2, cartesian_tag, cartesian_tag>
struct default_strategy<point_tag, point_tag, point1, point2, cartesian_tag, cartesian_tag>
{
typedef shift_and_calc_distance type;
};

View File

@@ -16,6 +16,8 @@ project boost-geometry-extensions-test
<include>../../test
<include>../../../boost/geometry/extensions/contrib/ttmath
<toolset>msvc:<asynch-exceptions>on
<toolset>msvc:<cxxflags>/bigobj
<host-os>windows,<toolset>intel:<cxxflags>/bigobj
<library>/boost/timer//boost_timer
;

View File

@@ -42,16 +42,8 @@
inline void check(double v, double ve, std::string const& name, std::string const& axis)
{
//BOOST_CHECK_CLOSE(v, ve, 0.001);
// Instead of (non-existing) BOOST_CHECK_CLOSE_MESSAGE(v, ve, 0.001, bla bla)
if (! boost::test_tools::check_is_close(v, ve, boost::test_tools::fpc::percent_tolerance(0.001)))
{
std::ostringstream out;
out << "\n" << name << " " << axis << " -> " << v << " != " << ve;
BOOST_ERROR(out.str());
}
// (non-existing) BOOST_CHECK_CLOSE_MESSAGE(v, ve, 0.001, "\n" << name << " " << axis << " -> " << v << " != " << ve);
BOOST_CHECK_CLOSE(v, ve, 0.001);
}
template <typename P>
@@ -210,7 +202,7 @@ void test_all()
test_forward<P>("putp6", 4.897000, 52.371000, 324931.055842, 5842588.644796, "+proj=putp6 +ellps=WGS84 +units=m");
test_forward<P>("putp6p", 4.897000, 52.371000, 338623.512107, 6396742.919679, "+proj=putp6p +ellps=WGS84 +units=m");
test_forward<P>("qua_aut", 4.897000, 52.371000, 370892.621714, 5629072.862494, "+proj=qua_aut +ellps=WGS84 +units=m");
test_forward<P>("robin", 4.897000, 52.371000, 394576.507489, 5571243.439235, "+proj=robin +ellps=WGS84 +units=m");
test_forward<P>("robin", 4.897000, 52.371000, 394576.507489, 5570940.631371, "+proj=robin +ellps=WGS84 +units=m");
test_forward<P>("rouss", 4.897000, 52.371000, 412826.227669, 6248368.849775, "+proj=rouss +ellps=WGS84 +units=m");
test_forward<P>("rpoly", 4.897000, 52.371000, 332447.130797, 5841164.662431, "+proj=rpoly +ellps=WGS84 +units=m");
test_forward<P>("sinu", 4.897000, 52.371000, 333528.909809, 5804625.044313, "+proj=sinu +ellps=WGS84 +units=m");
@@ -325,7 +317,7 @@ void test_all()
test_inverse<P>("putp6", 324931.055842, 5842588.644796, 4.897000, 52.371000, "+proj=putp6 +ellps=WGS84 +units=m");
test_inverse<P>("putp6p", 338623.512107, 6396742.919679, 4.897000, 52.371000, "+proj=putp6p +ellps=WGS84 +units=m");
test_inverse<P>("qua_aut", 370892.621714, 5629072.862494, 4.897000, 52.371000, "+proj=qua_aut +ellps=WGS84 +units=m");
test_inverse<P>("robin", 394576.507489, 5571243.439235, 4.897000, 52.371000, "+proj=robin +ellps=WGS84 +units=m");
test_inverse<P>("robin", 394576.507489, 5570940.631371, 4.897000, 52.371000, "+proj=robin +ellps=WGS84 +units=m");
test_inverse<P>("rouss", 412826.227669, 6248368.849775, 4.959853, 52.433747, "+proj=rouss +ellps=WGS84 +units=m"); // F/I: 8188.459174
test_inverse<P>("sinu", 333528.909809, 5804625.044313, 4.897000, 52.371000, "+proj=sinu +ellps=WGS84 +units=m");
test_inverse<P>("somerc", 545131.546415, 6833623.829215, 4.897000, 52.371000, "+proj=somerc +ellps=WGS84 +units=m");

View File

@@ -1,9 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2014, 2015.
// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
@@ -56,7 +56,6 @@
#include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/multi/algorithms/num_points.hpp>
#include <boost/geometry/algorithms/detail/centroid/translating_transformer.hpp>

View File

@@ -548,9 +548,8 @@ struct buffered_piece_collection
// reliable integer-based ring. All turns can be compared (inside) to this
// rings to see if they are inside.
for (typename piece_vector_type::iterator it = boost::begin(m_pieces);
it != boost::end(m_pieces);
++it)
for (typename boost::range_iterator<piece_vector_type>::type
it = boost::begin(m_pieces); it != boost::end(m_pieces); ++it)
{
piece& pc = *it;
int piece_segment_index = pc.first_seg_id.segment_index;
@@ -562,9 +561,9 @@ struct buffered_piece_collection
}
// Walk through them, in reverse to insert at right index
int index_offset = pc.robust_turns.size() - 1;
for (typename std::vector<robust_turn>::const_reverse_iterator
rit = pc.robust_turns.rbegin();
rit != pc.robust_turns.rend();
for (typename boost::range_reverse_iterator<const std::vector<robust_turn> >::type
rit = boost::const_rbegin(pc.robust_turns);
rit != boost::const_rend(pc.robust_turns);
++rit, --index_offset)
{
int const index_in_vector = 1 + rit->seg_id.segment_index - piece_segment_index;

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -19,6 +19,8 @@
#include <boost/geometry/strategies/buffer.hpp>
#include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
#include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
@@ -26,8 +28,6 @@
#include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/multi/algorithms/within.hpp>
namespace boost { namespace geometry
{

View File

@@ -9,6 +9,9 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_TURN_IN_PIECE_VISITOR
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_TURN_IN_PIECE_VISITOR
#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
#include <boost/geometry/arithmetic/dot_product.hpp>
@@ -172,7 +175,8 @@ public :
typename strategy_type::state_type state;
strategy_type strategy;
boost::ignore_unused(strategy);
for (std::size_t s = 0; s < piece.sections.size(); s++)
{
section_type const& section = piece.sections[s];

View File

@@ -185,10 +185,10 @@ public:
Geometry const
> segment_iterator_type;
typedef typename std::vector
typedef typename boost::range_const_iterator
<
segment_or_box_point
>::const_iterator seg_or_box_iterator_type;
std::vector<segment_or_box_point>
>::type seg_or_box_const_iterator;
typedef assign_new_min_iterator<SegmentOrBox> assign_new_value;
@@ -219,8 +219,9 @@ public:
// segment or box
comparable_return_type cd_min1(0);
point_iterator_type pit_min;
seg_or_box_iterator_type it_min1 = seg_or_box_points.begin();
seg_or_box_iterator_type it_min2 = ++seg_or_box_points.begin();
seg_or_box_const_iterator it_min1 = boost::const_begin(seg_or_box_points);
seg_or_box_const_iterator it_min2 = it_min1;
++it_min2;
bool first = true;
for (point_iterator_type pit = points_begin(geometry);
@@ -229,11 +230,11 @@ public:
comparable_return_type cd;
std::pair
<
seg_or_box_iterator_type, seg_or_box_iterator_type
seg_or_box_const_iterator, seg_or_box_const_iterator
> it_pair
= point_to_point_range::apply(*pit,
seg_or_box_points.begin(),
seg_or_box_points.end(),
boost::const_begin(seg_or_box_points),
boost::const_end(seg_or_box_points),
cstrategy,
cd);
@@ -250,12 +251,11 @@ public:
// segments of the geometry
comparable_return_type cd_min2(0);
segment_iterator_type sit_min;
typename std::vector<segment_or_box_point>::const_iterator it_min;
seg_or_box_const_iterator it_min;
first = true;
for (typename std::vector<segment_or_box_point>::const_iterator it
= seg_or_box_points.begin();
it != seg_or_box_points.end(); ++it, first = false)
for (seg_or_box_const_iterator it = boost::const_begin(seg_or_box_points);
it != boost::const_end(seg_or_box_points); ++it, first = false)
{
comparable_return_type cd;
segment_iterator_type sit

View File

@@ -1,9 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -36,8 +36,6 @@
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
// TODO: remove this after moving num_point from multi directory
#include <boost/geometry/multi/algorithms/num_points.hpp>
namespace boost { namespace geometry
{

View File

@@ -36,7 +36,10 @@ struct has_duplicates
static inline bool apply(Range const& range, VisitPolicy& visitor)
{
typedef typename closeable_view<Range const, Closure>::type view_type;
typedef typename boost::range_iterator<view_type const>::type iterator;
typedef typename boost::range_const_iterator
<
view_type const
>::type const_iterator;
view_type view(range);
@@ -47,9 +50,10 @@ struct has_duplicates
geometry::equal_to<typename boost::range_value<Range>::type> equal;
iterator it = boost::begin(view);
iterator next = ++boost::begin(view);
for (; next != boost::end(view); ++it, ++next)
const_iterator it = boost::const_begin(view);
const_iterator next = it;
++next;
for (; next != boost::const_end(view); ++it, ++next)
{
if ( equal(*it, *next) )
{

View File

@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2011-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2011-2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015 Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -9,10 +14,13 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_PARTITION_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_PARTITION_HPP
#include <cstddef>
#include <vector>
#include <boost/range/algorithm/copy.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/algorithms/assign.hpp>
namespace boost { namespace geometry
{
@@ -20,8 +28,6 @@ namespace boost { namespace geometry
namespace detail { namespace partition
{
typedef std::vector<std::size_t> index_vector_type;
template <int Dimension, typename Box>
inline void divide_box(Box const& box, Box& lower_box, Box& upper_box)
{
@@ -38,31 +44,26 @@ inline void divide_box(Box const& box, Box& lower_box, Box& upper_box)
geometry::set<min_corner, Dimension>(upper_box, mid);
}
// Divide collection into three subsets: lower, upper and oversized
// Divide forward_range into three subsets: lower, upper and oversized
// (not-fitting)
// (lower == left or bottom, upper == right or top)
template <typename OverlapsPolicy, typename InputCollection, typename Box>
template <typename OverlapsPolicy, typename Box, typename IteratorVector>
inline void divide_into_subsets(Box const& lower_box,
Box const& upper_box,
InputCollection const& collection,
index_vector_type const& input,
index_vector_type& lower,
index_vector_type& upper,
index_vector_type& exceeding)
IteratorVector const& input,
IteratorVector& lower,
IteratorVector& upper,
IteratorVector& exceeding)
{
typedef boost::range_iterator
typedef typename boost::range_iterator
<
index_vector_type const
>::type index_iterator_type;
IteratorVector const
>::type it_type;
for(index_iterator_type it = boost::begin(input);
it != boost::end(input);
++it)
for(it_type it = boost::begin(input); it != boost::end(input); ++it)
{
bool const lower_overlapping = OverlapsPolicy::apply(lower_box,
collection[*it]);
bool const upper_overlapping = OverlapsPolicy::apply(upper_box,
collection[*it]);
bool const lower_overlapping = OverlapsPolicy::apply(lower_box, **it);
bool const upper_overlapping = OverlapsPolicy::apply(upper_box, **it);
if (lower_overlapping && upper_overlapping)
{
@@ -84,99 +85,109 @@ inline void divide_into_subsets(Box const& lower_box,
}
}
template <typename ExpandPolicy, typename Box, typename InputCollection>
inline void expand_with_elements(Box& total,
InputCollection const& collection,
index_vector_type const& input)
template
<
typename ExpandPolicy,
typename Box,
typename IteratorVector
>
inline void expand_with_elements(Box& total, IteratorVector const& input)
{
typedef boost::range_iterator<index_vector_type const>::type it_type;
typedef typename boost::range_iterator<IteratorVector const>::type it_type;
for(it_type it = boost::begin(input); it != boost::end(input); ++it)
{
ExpandPolicy::apply(total, collection[*it]);
ExpandPolicy::apply(total, **it);
}
}
// Match collection with itself
template <typename InputCollection, typename Policy>
inline void handle_one(InputCollection const& collection,
index_vector_type const& input,
Policy& policy)
// Match forward_range with itself
template <typename Policy, typename IteratorVector>
inline void handle_one(IteratorVector const& input, Policy& policy)
{
if (boost::size(input) == 0)
{
return;
}
typedef boost::range_iterator<index_vector_type const>::type
index_iterator_type;
typedef typename boost::range_iterator<IteratorVector const>::type it_type;
// Quadratic behaviour at lowest level (lowest quad, or all exceeding)
for(index_iterator_type it1 = boost::begin(input);
it1 != boost::end(input);
++it1)
for (it_type it1 = boost::begin(input); it1 != boost::end(input); ++it1)
{
index_iterator_type it2 = it1;
for(++it2; it2 != boost::end(input); ++it2)
it_type it2 = it1;
for (++it2; it2 != boost::end(input); ++it2)
{
policy.apply(collection[*it1], collection[*it2]);
policy.apply(**it1, **it2);
}
}
}
// Match collection 1 with collection 2
// Match forward range 1 with forward range 2
template
<
typename InputCollection1,
typename InputCollection2,
typename Policy
typename Policy,
typename IteratorVector1,
typename IteratorVector2
>
inline void handle_two(
InputCollection1 const& collection1, index_vector_type const& input1,
InputCollection2 const& collection2, index_vector_type const& input2,
inline void handle_two(IteratorVector1 const& input1,
IteratorVector2 const& input2,
Policy& policy)
{
typedef typename boost::range_iterator
<
IteratorVector1 const
>::type iterator_type1;
typedef typename boost::range_iterator
<
IteratorVector2 const
>::type iterator_type2;
if (boost::size(input1) == 0 || boost::size(input2) == 0)
{
return;
}
typedef boost::range_iterator
<
index_vector_type const
>::type index_iterator_type;
for(index_iterator_type it1 = boost::begin(input1);
for(iterator_type1 it1 = boost::begin(input1);
it1 != boost::end(input1);
++it1)
{
for(index_iterator_type it2 = boost::begin(input2);
for(iterator_type2 it2 = boost::begin(input2);
it2 != boost::end(input2);
++it2)
{
policy.apply(collection1[*it1], collection2[*it2]);
policy.apply(**it1, **it2);
}
}
}
inline bool recurse_ok(index_vector_type const& input,
template <typename IteratorVector>
inline bool recurse_ok(IteratorVector const& input,
std::size_t min_elements, std::size_t level)
{
return boost::size(input) >= min_elements
&& level < 100;
}
inline bool recurse_ok(index_vector_type const& input1,
index_vector_type const& input2,
template <typename IteratorVector1, typename IteratorVector2>
inline bool recurse_ok(IteratorVector1 const& input1,
IteratorVector2 const& input2,
std::size_t min_elements, std::size_t level)
{
return boost::size(input1) >= min_elements
&& recurse_ok(input2, min_elements, level);
}
inline bool recurse_ok(index_vector_type const& input1,
index_vector_type const& input2,
index_vector_type const& input3,
template
<
typename IteratorVector1,
typename IteratorVector2,
typename IteratorVector3
>
inline bool recurse_ok(IteratorVector1 const& input1,
IteratorVector2 const& input2,
IteratorVector3 const& input3,
std::size_t min_elements, std::size_t level)
{
return boost::size(input1) >= min_elements
@@ -193,7 +204,7 @@ template
typename ExpandPolicy2,
typename VisitBoxPolicy
>
class partition_two_collections;
class partition_two_ranges;
template
@@ -204,79 +215,71 @@ template
typename ExpandPolicy,
typename VisitBoxPolicy
>
class partition_one_collection
class partition_one_range
{
typedef std::vector<std::size_t> index_vector_type;
template <typename InputCollection>
static inline Box get_new_box(InputCollection const& collection,
index_vector_type const& input)
template <typename IteratorVector>
static inline Box get_new_box(IteratorVector const& input)
{
Box box;
geometry::assign_inverse(box);
expand_with_elements<ExpandPolicy>(box, collection, input);
expand_with_elements<ExpandPolicy>(box, input);
return box;
}
template <typename InputCollection, typename Policy>
template <typename Policy, typename IteratorVector>
static inline void next_level(Box const& box,
InputCollection const& collection,
index_vector_type const& input,
IteratorVector const& input,
std::size_t level, std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
{
if (recurse_ok(input, min_elements, level))
{
partition_one_collection
partition_one_range
<
1 - Dimension,
Box,
OverlapsPolicy,
ExpandPolicy,
VisitBoxPolicy
>::apply(box, collection, input,
level + 1, min_elements, policy, box_policy);
>::apply(box, input, level + 1, min_elements, policy, box_policy);
}
else
{
handle_one(collection, input, policy);
handle_one(input, policy);
}
}
// Function to switch to two collections if there are geometries exceeding
// the separation line
template <typename InputCollection, typename Policy>
// Function to switch to two forward ranges if there are
// geometries exceeding the separation line
template <typename Policy, typename IteratorVector>
static inline void next_level2(Box const& box,
InputCollection const& collection,
index_vector_type const& input1,
index_vector_type const& input2,
IteratorVector const& input1,
IteratorVector const& input2,
std::size_t level, std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
{
if (recurse_ok(input1, input2, min_elements, level))
{
partition_two_collections
partition_two_ranges
<
1 - Dimension,
Box,
OverlapsPolicy, OverlapsPolicy,
ExpandPolicy, ExpandPolicy,
VisitBoxPolicy
>::apply(box, collection, input1, collection, input2,
level + 1, min_elements, policy, box_policy);
>::apply(box, input1, input2, level + 1, min_elements,
policy, box_policy);
}
else
{
handle_two(collection, input1, collection, input2, policy);
handle_two(input1, input2, policy);
}
}
public :
template <typename InputCollection, typename Policy>
template <typename Policy, typename IteratorVector>
static inline void apply(Box const& box,
InputCollection const& collection,
index_vector_type const& input,
IteratorVector const& input,
std::size_t level,
std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
@@ -286,33 +289,31 @@ public :
Box lower_box, upper_box;
divide_box<Dimension>(box, lower_box, upper_box);
index_vector_type lower, upper, exceeding;
divide_into_subsets<OverlapsPolicy>(lower_box, upper_box, collection,
IteratorVector lower, upper, exceeding;
divide_into_subsets<OverlapsPolicy>(lower_box, upper_box,
input, lower, upper, exceeding);
if (boost::size(exceeding) > 0)
{
// Get the box of exceeding-only
Box exceeding_box = get_new_box(collection, exceeding);
Box exceeding_box = get_new_box(exceeding);
// Recursively do exceeding elements only, in next dimension they
// will probably be less exceeding within the new box
next_level(exceeding_box, collection, exceeding, level,
min_elements, policy, box_policy);
next_level(exceeding_box, exceeding, level, min_elements,
policy, box_policy);
// Switch to two collections, combine exceeding with lower resp upper
// but not lower/lower, upper/upper
next_level2(exceeding_box, collection, exceeding, lower, level,
min_elements, policy, box_policy);
next_level2(exceeding_box, collection, exceeding, upper, level,
min_elements, policy, box_policy);
// Switch to two forward ranges, combine exceeding with
// lower resp upper, but not lower/lower, upper/upper
next_level2(exceeding_box, exceeding, lower, level, min_elements,
policy, box_policy);
next_level2(exceeding_box, exceeding, upper, level, min_elements,
policy, box_policy);
}
// Recursively call operation both parts
next_level(lower_box, collection, lower, level, min_elements,
policy, box_policy);
next_level(upper_box, collection, upper, level, min_elements,
policy, box_policy);
next_level(lower_box, lower, level, min_elements, policy, box_policy);
next_level(upper_box, upper, level, min_elements, policy, box_policy);
}
};
@@ -326,25 +327,21 @@ template
typename ExpandPolicy2,
typename VisitBoxPolicy
>
class partition_two_collections
class partition_two_ranges
{
typedef std::vector<std::size_t> index_vector_type;
template
<
typename InputCollection1,
typename InputCollection2,
typename Policy
typename Policy,
typename IteratorVector1,
typename IteratorVector2
>
static inline void next_level(Box const& box,
InputCollection1 const& collection1,
index_vector_type const& input1,
InputCollection2 const& collection2,
index_vector_type const& input2,
IteratorVector1 const& input1,
IteratorVector2 const& input2,
std::size_t level, std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
{
partition_two_collections
partition_two_ranges
<
1 - Dimension,
Box,
@@ -353,50 +350,38 @@ class partition_two_collections
ExpandPolicy1,
ExpandPolicy2,
VisitBoxPolicy
>::apply(box, collection1, input1, collection2, input2,
level + 1, min_elements,
policy, box_policy);
>::apply(box, input1, input2, level + 1, min_elements,
policy, box_policy);
}
template
<
typename ExpandPolicy,
typename InputCollection
>
static inline Box get_new_box(InputCollection const& collection,
index_vector_type const& input)
template <typename ExpandPolicy, typename IteratorVector>
static inline Box get_new_box(IteratorVector const& input)
{
Box box;
geometry::assign_inverse(box);
expand_with_elements<ExpandPolicy>(box, collection, input);
expand_with_elements<ExpandPolicy>(box, input);
return box;
}
template
<
typename InputCollection1,
typename InputCollection2
>
static inline Box get_new_box(InputCollection1 const& collection1,
index_vector_type const& input1,
InputCollection2 const& collection2,
index_vector_type const& input2)
template <typename IteratorVector1, typename IteratorVector2>
static inline Box get_new_box(IteratorVector1 const& input1,
IteratorVector2 const& input2)
{
Box box = get_new_box<ExpandPolicy1>(collection1, input1);
expand_with_elements<ExpandPolicy2>(box, collection2, input2);
Box box = get_new_box<ExpandPolicy1>(input1);
expand_with_elements<ExpandPolicy2>(box, input2);
return box;
}
public :
template
<
typename InputCollection1,
typename InputCollection2,
typename Policy
typename Policy,
typename IteratorVector1,
typename IteratorVector2
>
static inline void apply(Box const& box,
InputCollection1 const& collection1, index_vector_type const& input1,
InputCollection2 const& collection2, index_vector_type const& input2,
IteratorVector1 const& input1,
IteratorVector2 const& input2,
std::size_t level,
std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
@@ -406,11 +391,11 @@ public :
Box lower_box, upper_box;
divide_box<Dimension>(box, lower_box, upper_box);
index_vector_type lower1, upper1, exceeding1;
index_vector_type lower2, upper2, exceeding2;
divide_into_subsets<OverlapsPolicy1>(lower_box, upper_box, collection1,
IteratorVector1 lower1, upper1, exceeding1;
IteratorVector2 lower2, upper2, exceeding2;
divide_into_subsets<OverlapsPolicy1>(lower_box, upper_box,
input1, lower1, upper1, exceeding1);
divide_into_subsets<OverlapsPolicy2>(lower_box, upper_box, collection2,
divide_into_subsets<OverlapsPolicy2>(lower_box, upper_box,
input2, lower2, upper2, exceeding2);
if (boost::size(exceeding1) > 0)
@@ -419,35 +404,31 @@ public :
if (recurse_ok(exceeding1, exceeding2, min_elements, level))
{
Box exceeding_box = get_new_box(collection1, exceeding1,
collection2, exceeding2);
next_level(exceeding_box, collection1, exceeding1,
collection2, exceeding2, level,
min_elements, policy, box_policy);
Box exceeding_box = get_new_box(exceeding1, exceeding2);
next_level(exceeding_box, exceeding1, exceeding2, level,
min_elements, policy, box_policy);
}
else
{
handle_two(collection1, exceeding1, collection2, exceeding2,
policy);
handle_two(exceeding1, exceeding2, policy);
}
// All exceeding from 1 with lower and upper of 2:
// (Check sizes of all three collections to avoid recurse into
// (Check sizes of all three forward ranges to avoid recurse into
// the same combinations again and again)
if (recurse_ok(lower2, upper2, exceeding1, min_elements, level))
{
Box exceeding_box
= get_new_box<ExpandPolicy1>(collection1, exceeding1);
next_level(exceeding_box, collection1, exceeding1,
collection2, lower2, level, min_elements, policy, box_policy);
next_level(exceeding_box, collection1, exceeding1,
collection2, upper2, level, min_elements, policy, box_policy);
Box exceeding_box = get_new_box<ExpandPolicy1>(exceeding1);
next_level(exceeding_box, exceeding1, lower2, level,
min_elements, policy, box_policy);
next_level(exceeding_box, exceeding1, upper2, level,
min_elements, policy, box_policy);
}
else
{
handle_two(collection1, exceeding1, collection2, lower2, policy);
handle_two(collection1, exceeding1, collection2, upper2, policy);
handle_two(exceeding1, lower2, policy);
handle_two(exceeding1, upper2, policy);
}
}
@@ -456,37 +437,36 @@ public :
// All exceeding from 2 with lower and upper of 1:
if (recurse_ok(lower1, upper1, exceeding2, min_elements, level))
{
Box exceeding_box
= get_new_box<ExpandPolicy2>(collection2, exceeding2);
next_level(exceeding_box, collection1, lower1,
collection2, exceeding2, level, min_elements, policy, box_policy);
next_level(exceeding_box, collection1, upper1,
collection2, exceeding2, level, min_elements, policy, box_policy);
Box exceeding_box = get_new_box<ExpandPolicy2>(exceeding2);
next_level(exceeding_box, lower1, exceeding2, level,
min_elements, policy, box_policy);
next_level(exceeding_box, upper1, exceeding2, level,
min_elements, policy, box_policy);
}
else
{
handle_two(collection1, lower1, collection2, exceeding2, policy);
handle_two(collection1, upper1, collection2, exceeding2, policy);
handle_two(lower1, exceeding2, policy);
handle_two(upper1, exceeding2, policy);
}
}
if (recurse_ok(lower1, lower2, min_elements, level))
{
next_level(lower_box, collection1, lower1, collection2, lower2, level,
min_elements, policy, box_policy);
next_level(lower_box, lower1, lower2, level,
min_elements, policy, box_policy);
}
else
{
handle_two(collection1, lower1, collection2, lower2, policy);
handle_two(lower1, lower2, policy);
}
if (recurse_ok(upper1, upper2, min_elements, level))
{
next_level(upper_box, collection1, upper1, collection2, upper2, level,
min_elements, policy, box_policy);
next_level(upper_box, upper1, upper2, level,
min_elements, policy, box_policy);
}
else
{
handle_two(collection1, upper1, collection2, upper2, policy);
handle_two(upper1, upper2, policy);
}
}
};
@@ -523,63 +503,67 @@ template
>
class partition
{
typedef std::vector<std::size_t> index_vector_type;
template <typename ExpandPolicy, typename IncludePolicy, typename InputCollection>
static inline void expand_to_collection(InputCollection const& collection,
Box& total, index_vector_type& index_vector)
template
<
typename ExpandPolicy,
typename IncludePolicy,
typename ForwardRange,
typename IteratorVector
>
static inline void expand_to_range(ForwardRange const& forward_range,
Box& total, IteratorVector& iterator_vector)
{
std::size_t index = 0;
for(typename boost::range_iterator<InputCollection const>::type it
= boost::begin(collection);
it != boost::end(collection);
++it, ++index)
for(typename boost::range_iterator<ForwardRange const>::type it
= boost::begin(forward_range);
it != boost::end(forward_range);
++it)
{
if (IncludePolicy::apply(*it))
{
ExpandPolicy::apply(total, *it);
index_vector.push_back(index);
iterator_vector.push_back(it);
}
}
}
public :
template <typename InputCollection, typename VisitPolicy>
static inline void apply(InputCollection const& collection,
template <typename ForwardRange, typename VisitPolicy>
static inline void apply(ForwardRange const& forward_range,
VisitPolicy& visitor,
std::size_t min_elements = 16,
VisitBoxPolicy box_visitor = detail::partition::visit_no_policy()
)
{
if (std::size_t(boost::size(collection)) > min_elements)
typedef typename boost::range_iterator
<
ForwardRange const
>::type iterator_type;
if (std::size_t(boost::size(forward_range)) > min_elements)
{
index_vector_type index_vector;
std::vector<iterator_type> iterator_vector;
Box total;
assign_inverse(total);
expand_to_collection<ExpandPolicy1, IncludePolicy1>(collection,
total, index_vector);
expand_to_range<ExpandPolicy1, IncludePolicy1>(forward_range,
total, iterator_vector);
detail::partition::partition_one_collection
detail::partition::partition_one_range
<
0, Box,
OverlapsPolicy1,
ExpandPolicy1,
VisitBoxPolicy
>::apply(total, collection, index_vector, 0, min_elements,
visitor, box_visitor);
>::apply(total, iterator_vector, 0, min_elements,
visitor, box_visitor);
}
else
{
typedef typename boost::range_iterator
<
InputCollection const
>::type iterator_type;
for(iterator_type it1 = boost::begin(collection);
it1 != boost::end(collection);
for(iterator_type it1 = boost::begin(forward_range);
it1 != boost::end(forward_range);
++it1)
{
iterator_type it2 = it1;
for(++it2; it2 != boost::end(collection); ++it2)
for(++it2; it2 != boost::end(forward_range); ++it2)
{
visitor.apply(*it1, *it2);
}
@@ -589,53 +573,55 @@ public :
template
<
typename InputCollection1,
typename InputCollection2,
typename ForwardRange1,
typename ForwardRange2,
typename VisitPolicy
>
static inline void apply(InputCollection1 const& collection1,
InputCollection2 const& collection2,
static inline void apply(ForwardRange1 const& forward_range1,
ForwardRange2 const& forward_range2,
VisitPolicy& visitor,
std::size_t min_elements = 16,
VisitBoxPolicy box_visitor = detail::partition::visit_no_policy()
VisitBoxPolicy box_visitor
= detail::partition::visit_no_policy()
)
{
if (std::size_t(boost::size(collection1)) > min_elements
&& std::size_t(boost::size(collection2)) > min_elements)
typedef typename boost::range_iterator
<
ForwardRange1 const
>::type iterator_type1;
typedef typename boost::range_iterator
<
ForwardRange2 const
>::type iterator_type2;
if (std::size_t(boost::size(forward_range1)) > min_elements
&& std::size_t(boost::size(forward_range2)) > min_elements)
{
index_vector_type index_vector1, index_vector2;
std::vector<iterator_type1> iterator_vector1;
std::vector<iterator_type2> iterator_vector2;
Box total;
assign_inverse(total);
expand_to_collection<ExpandPolicy1, IncludePolicy1>(collection1,
total, index_vector1);
expand_to_collection<ExpandPolicy2, IncludePolicy2>(collection2,
total, index_vector2);
expand_to_range<ExpandPolicy1, IncludePolicy1>(forward_range1,
total, iterator_vector1);
expand_to_range<ExpandPolicy2, IncludePolicy2>(forward_range2,
total, iterator_vector2);
detail::partition::partition_two_collections
detail::partition::partition_two_ranges
<
0, Box, OverlapsPolicy1, OverlapsPolicy2,
ExpandPolicy1, ExpandPolicy2, VisitBoxPolicy
>::apply(total,
collection1, index_vector1,
collection2, index_vector2,
0, min_elements, visitor, box_visitor);
>::apply(total, iterator_vector1, iterator_vector2,
0, min_elements, visitor, box_visitor);
}
else
{
typedef typename boost::range_iterator
<
InputCollection1 const
>::type iterator_type1;
typedef typename boost::range_iterator
<
InputCollection2 const
>::type iterator_type2;
for(iterator_type1 it1 = boost::begin(collection1);
it1 != boost::end(collection1);
for(iterator_type1 it1 = boost::begin(forward_range1);
it1 != boost::end(forward_range1);
++it1)
{
for(iterator_type2 it2 = boost::begin(collection2);
it2 != boost::end(collection2);
for(iterator_type2 it2 = boost::begin(forward_range2);
it2 != boost::end(forward_range2);
++it2)
{
visitor.apply(*it1, *it2);

View File

@@ -236,11 +236,11 @@ struct interrupt_dispatch<Mask, true>
static inline bool apply(Mask const& mask)
{
char m = mask.template get<F1, F2>();
return check<V>(m);
return check_element<V>(m);
}
template <char V>
static inline bool check(char m)
static inline bool check_element(char m)
{
if ( BOOST_GEOMETRY_CONDITION(V >= '0' && V <= '9') )
{
@@ -395,7 +395,7 @@ inline bool may_update(Mask const& mask, Matrix const& matrix)
::template apply<F1, F2, D>(mask, matrix);
}
// check()
// check_matrix()
template <typename Mask>
struct check_dispatch
@@ -486,7 +486,7 @@ struct check_dispatch< boost::tuples::cons<Head, Tail> >
};
template <typename Mask, typename Matrix>
inline bool check(Mask const& mask, Matrix const& matrix)
inline bool check_matrix(Mask const& mask, Matrix const& matrix)
{
return check_dispatch<Mask>::apply(mask, matrix);
}
@@ -547,7 +547,7 @@ public:
result_type result() const
{
return !interrupt
&& check(m_mask, static_cast<base_t const&>(*this));
&& check_matrix(m_mask, static_cast<base_t const&>(*this));
}
template <field F1, field F2, char D>
@@ -965,7 +965,7 @@ struct static_check_dispatch<StaticMask, true>
};
template <typename StaticMask>
struct static_check
struct static_check_matrix
{
template <typename Matrix>
static inline bool apply(Matrix const& matrix)
@@ -998,7 +998,7 @@ public:
result_type result() const
{
return (!Interrupt || !interrupt)
&& static_check<StaticMask>::
&& static_check_matrix<StaticMask>::
apply(static_cast<base_t const&>(*this));
}

View File

@@ -1,8 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2014, 2015.
// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -83,7 +88,6 @@ namespace ttmath
return ACos(v);
}
template <uint Exponent, uint Mantissa>
inline Big<Exponent, Mantissa> atan2(Big<Exponent, Mantissa> const& y, Big<Exponent, Mantissa> const& x)
{
@@ -103,6 +107,13 @@ namespace ttmath
return two * ATan((sqrt(x * x + y * y) - x) / y);
}
// needed in order to work with boost::geometry::math::mod
template <uint Exponent, uint Mantissa>
inline Big<Exponent, Mantissa> mod(Big<Exponent, Mantissa> const& x,
Big<Exponent, Mantissa> const& y)
{
return Mod(x, y);
}
}
// Specific structure implementing constructor
@@ -116,18 +127,18 @@ struct ttmath_big : ttmath::Big<1,4>
: ttmath::Big<1,4>(v)
{}
// unary operator+() is implemented for completeness
inline ttmath_big const& operator+() const
{
return *this;
}
// needed in order to work with boost::geometry::math::abs
inline ttmath_big operator-() const
{
return ttmath::Big<1,4>::operator-();
}
// needed because unary operator-() is defined (above)
inline ttmath_big operator-(ttmath_big const& other) const
{
return ttmath::Big<1,4>::operator-(other);
}
/*
inline operator double() const
{
@@ -141,6 +152,29 @@ struct ttmath_big : ttmath::Big<1,4>
*/
};
// arithmetic operators for ttmath_big objects, defined as free functions
inline ttmath_big operator+(ttmath_big const& x, ttmath_big const& y)
{
return static_cast<ttmath::Big<1,4> const&>(x).operator+(y);
}
inline ttmath_big operator-(ttmath_big const& x, ttmath_big const& y)
{
return static_cast<ttmath::Big<1,4> const&>(x).operator-(y);
}
inline ttmath_big operator*(ttmath_big const& x, ttmath_big const& y)
{
return static_cast<ttmath::Big<1,4> const&>(x).operator*(y);
}
inline ttmath_big operator/(ttmath_big const& x, ttmath_big const& y)
{
return static_cast<ttmath::Big<1,4> const&>(x).operator/(y);
}
namespace boost{ namespace geometry { namespace math
{

View File

@@ -254,15 +254,15 @@ namespace strategy
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
template <template<typename> class CS>
struct strategy_parse<geographic_tag, CS<degree> >
template <template<typename> class CoordinateSystem>
struct strategy_parse<geographic_tag, CoordinateSystem<degree> >
{
typedef strategy::dms_parser<false> type;
};
template <template<typename> class CS>
struct strategy_parse<geographic_tag, CS<radian> >
template <template<typename> class CoordinateSystem>
struct strategy_parse<geographic_tag, CoordinateSystem<radian> >
{
typedef strategy::dms_parser<true> type;
};

View File

@@ -115,7 +115,7 @@ namespace boost { namespace geometry { namespace projections
ct = cos(t); st = sin(t);
Az = atan2(sin(lp_lon) * ct, this->m_proj_parm.cosph0 * st - this->m_proj_parm.sinph0 * coslam * ct);
cA = cos(Az); sA = sin(Az);
s = aasin( fabs(sA) < TOL ?
s = aasin(fabs(sA) < TOL ?
(this->m_proj_parm.cosph0 * st - this->m_proj_parm.sinph0 * coslam * ct) / cA :
sin(lp_lon) * ct / sA );
H = this->m_proj_parm.He * cA;

View File

@@ -135,6 +135,7 @@ namespace boost { namespace geometry { namespace projections
\par Projection characteristics
- Miscellaneous
- Spheroid
- no inverse
\par Example
\image html ex_aitoff.gif
*/
@@ -156,6 +157,7 @@ namespace boost { namespace geometry { namespace projections
\par Projection characteristics
- Miscellaneous
- Spheroid
- no inverse
- lat_1
\par Example
\image html ex_wintri.gif

View File

@@ -41,7 +41,6 @@
#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
#include <boost/geometry/extensions/gis/projections/proj/moll.hpp>
#include <boost/geometry/extensions/gis/projections/proj/gn_sinu.hpp>

View File

@@ -49,8 +49,8 @@ namespace boost { namespace geometry { namespace projections
static const int NITER = 20;
static const double EPS = 1e-7;
static const double ONETOL = 1.000001;
static const double CN = 2.67595;
static const double CS = 2.43763;
static const double CN_ = 2.67595;
static const double CS_ = 2.43763;
static const double RCN = 0.37369906014686373063;
static const double RCS = 0.41023453108141924738;
static const double FYCN = 1.75859;
@@ -80,7 +80,7 @@ namespace boost { namespace geometry { namespace projections
double th1, c;
int i;
c = sin(lp_lat) * (lp_lat < 0. ? CS : CN);
c = sin(lp_lat) * (lp_lat < 0. ? CS_ : CN_);
for (i = NITER; i; --i) {
lp_lat -= th1 = (lp_lat + sin(lp_lat) - c) / (1. + cos(lp_lat));
if (fabs(th1) < EPS) break;

View File

@@ -117,7 +117,8 @@ namespace boost { namespace geometry { namespace projections
template <typename Parameters>
void setup_lcca(Parameters& par, par_lcca& proj_parm)
{
double s2p0, N0, R0, tan0/*, tan20*/;
double s2p0, N0, R0, tan0, tan20;
boost::ignore_unused(tan20);
pj_enfn(par.es, proj_parm.en);
if (!pj_param(par.params, "tlat_0").i) throw proj_exception(50);
if (par.phi0 == 0.) throw proj_exception(51);
@@ -128,7 +129,7 @@ namespace boost { namespace geometry { namespace projections
N0 = sqrt(R0);
R0 *= par.one_es * N0;
tan0 = tan(par.phi0);
//tan20 = tan0 * tan0;
tan20 = tan0 * tan0;
proj_parm.r0 = N0 / tan0;
proj_parm.C = 1. / (6. * R0 * N0);
// par.inv = e_inverse;

View File

@@ -46,7 +46,7 @@ namespace boost { namespace geometry { namespace projections
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace mbtfpp{
static const double CS = .95257934441568037152;
static const double CS_ = .95257934441568037152;
static const double FXC = .92582009977255146156;
static const double FYC = 3.40168025708304504493;
static const double C23 = .66666666666666666666;
@@ -70,7 +70,7 @@ namespace boost { namespace geometry { namespace projections
inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
{
lp_lat = asin(CS * sin(lp_lat));
lp_lat = asin(CS_ * sin(lp_lat));
xy_x = FXC * lp_lon * (2. * cos(C23 * lp_lat) - 1.);
xy_y = FYC * sin(C13 * lp_lat);
}
@@ -84,7 +84,7 @@ namespace boost { namespace geometry { namespace projections
} else
lp_lat = asin(lp_lat);
lp_lon = xy_x / ( FXC * (2. * cos(C23 * (lp_lat *= 3.)) - 1.) );
if (fabs(lp_lat = sin(lp_lat) / CS) >= 1.) {
if (fabs(lp_lat = sin(lp_lat) / CS_) >= 1.) {
if (fabs(lp_lat) > ONEEPS) throw proj_exception();
else lp_lat = (lp_lat < 0.) ? -HALFPI : HALFPI;
} else

View File

@@ -142,7 +142,6 @@ namespace boost { namespace geometry { namespace projections
\tparam Parameters parameter type
\par Projection characteristics
- Pseudocylindrical
- no inverse
- Spheroid
\par Example
\image html ex_putp3p.gif

View File

@@ -98,7 +98,7 @@ namespace boost { namespace geometry { namespace projections
lp_lat = xy_y / this->m_proj_parm.C_y;
r = sqrt(1. + lp_lat * lp_lat);
lp_lon = xy_x / (this->m_proj_parm.C_x * (this->m_proj_parm.D - r));
lp_lat = aasin( ( (this->m_proj_parm.A - r) * lp_lat - log(lp_lat + r) ) / this->m_proj_parm.B);
lp_lat = aasin(( (this->m_proj_parm.A - r) * lp_lat - log(lp_lat + r) ) / this->m_proj_parm.B);
}
};

View File

@@ -55,49 +55,54 @@ namespace boost { namespace geometry { namespace projections
static const double ONEEPS = 1.000001;
static const double EPS = 1e-8;
/* note: following terms based upon 5 deg. intervals in degrees. */
static struct COEFS {
struct COEFS {
double c0, c1, c2, c3;
} X[] = {
{1, -5.67239e-12, -7.15511e-05, 3.11028e-06},
{0.9986, -0.000482241, -2.4897e-05, -1.33094e-06},
{0.9954, -0.000831031, -4.4861e-05, -9.86588e-07},
{0.99, -0.00135363, -5.96598e-05, 3.67749e-06},
{0.9822, -0.00167442, -4.4975e-06, -5.72394e-06},
{0.973, -0.00214869, -9.03565e-05, 1.88767e-08},
{0.96, -0.00305084, -9.00732e-05, 1.64869e-06},
{0.9427, -0.00382792, -6.53428e-05, -2.61493e-06},
{0.9216, -0.00467747, -0.000104566, 4.8122e-06},
{0.8962, -0.00536222, -3.23834e-05, -5.43445e-06},
{0.8679, -0.00609364, -0.0001139, 3.32521e-06},
{0.835, -0.00698325, -6.40219e-05, 9.34582e-07},
{0.7986, -0.00755337, -5.00038e-05, 9.35532e-07},
{0.7597, -0.00798325, -3.59716e-05, -2.27604e-06},
{0.7186, -0.00851366, -7.0112e-05, -8.63072e-06},
{0.6732, -0.00986209, -0.000199572, 1.91978e-05},
{0.6213, -0.010418, 8.83948e-05, 6.24031e-06},
{0.5722, -0.00906601, 0.000181999, 6.24033e-06},
{0.5322, 0.,0.,0.} },
Y[] = {
{0, 0.0124, 3.72529e-10, 1.15484e-09},
{0.062, 0.0124001, 1.76951e-08, -5.92321e-09},
{0.124, 0.0123998, -7.09668e-08, 2.25753e-08},
{0.186, 0.0124008, 2.66917e-07, -8.44523e-08},
{0.248, 0.0123971, -9.99682e-07, 3.15569e-07},
{0.31, 0.0124108, 3.73349e-06, -1.1779e-06},
{0.372, 0.0123598, -1.3935e-05, 4.39588e-06},
{0.434, 0.0125501, 5.20034e-05, -1.00051e-05},
{0.4958, 0.0123198, -9.80735e-05, 9.22397e-06},
{0.5571, 0.0120308, 4.02857e-05, -5.2901e-06},
{0.6176, 0.0120369, -3.90662e-05, 7.36117e-07},
{0.6769, 0.0117015, -2.80246e-05, -8.54283e-07},
{0.7346, 0.0113572, -4.08389e-05, -5.18524e-07},
{0.7903, 0.0109099, -4.86169e-05, -1.0718e-06},
{0.8435, 0.0103433, -6.46934e-05, 5.36384e-09},
{0.8936, 0.00969679, -6.46129e-05, -8.54894e-06},
{0.9394, 0.00840949, -0.000192847, -4.21023e-06},
{0.9761, 0.00616525, -0.000256001, -4.21021e-06},
{1., 0.,0.,0} };
};
static const struct COEFS X[] = {
{1, 2.2199e-17, -7.15515e-05, 3.1103e-06},
{0.9986, -0.000482243, -2.4897e-05, -1.3309e-06},
{0.9954, -0.00083103, -4.48605e-05, -9.86701e-07},
{0.99, -0.00135364, -5.9661e-05, 3.6777e-06},
{0.9822, -0.00167442, -4.49547e-06, -5.72411e-06},
{0.973, -0.00214868, -9.03571e-05, 1.8736e-08},
{0.96, -0.00305085, -9.00761e-05, 1.64917e-06},
{0.9427, -0.00382792, -6.53386e-05, -2.6154e-06},
{0.9216, -0.00467746, -0.00010457, 4.81243e-06},
{0.8962, -0.00536223, -3.23831e-05, -5.43432e-06},
{0.8679, -0.00609363, -0.000113898, 3.32484e-06},
{0.835, -0.00698325, -6.40253e-05, 9.34959e-07},
{0.7986, -0.00755338, -5.00009e-05, 9.35324e-07},
{0.7597, -0.00798324, -3.5971e-05, -2.27626e-06},
{0.7186, -0.00851367, -7.01149e-05, -8.6303e-06},
{0.6732, -0.00986209, -0.000199569, 1.91974e-05},
{0.6213, -0.010418, 8.83923e-05, 6.24051e-06},
{0.5722, -0.00906601, 0.000182, 6.24051e-06},
{0.5322, -0.00677797, 0.000275608, 6.24051e-06}
};
static const struct COEFS Y[] = {
{-5.20417e-18, 0.0124, 1.21431e-18, -8.45284e-11},
{0.062, 0.0124, -1.26793e-09, 4.22642e-10},
{0.124, 0.0124, 5.07171e-09, -1.60604e-09},
{0.186, 0.0123999, -1.90189e-08, 6.00152e-09},
{0.248, 0.0124002, 7.10039e-08, -2.24e-08},
{0.31, 0.0123992, -2.64997e-07, 8.35986e-08},
{0.372, 0.0124029, 9.88983e-07, -3.11994e-07},
{0.434, 0.0123893, -3.69093e-06, -4.35621e-07},
{0.4958, 0.0123198, -1.02252e-05, -3.45523e-07},
{0.5571, 0.0121916, -1.54081e-05, -5.82288e-07},
{0.6176, 0.0119938, -2.41424e-05, -5.25327e-07},
{0.6769, 0.011713, -3.20223e-05, -5.16405e-07},
{0.7346, 0.0113541, -3.97684e-05, -6.09052e-07},
{0.7903, 0.0109107, -4.89042e-05, -1.04739e-06},
{0.8435, 0.0103431, -6.4615e-05, -1.40374e-09},
{0.8936, 0.00969686, -6.4636e-05, -8.547e-06},
{0.9394, 0.00840947, -0.000192841, -4.2106e-06},
{0.9761, 0.00616527, -0.000256, -4.2106e-06},
{1, 0.00328947, -0.000319159, -4.2106e-06}
};
// template class, using CRTP to implement forward/inverse
template <typename Geographic, typename Cartesian, typename Parameters>

View File

@@ -112,7 +112,6 @@ namespace boost { namespace geometry { namespace projections
break;
case PCONIC:
rho = this->m_proj_parm.c2 * (this->m_proj_parm.c1 - tan(lp_lat - this->m_proj_parm.sig));
// rho = this->m_proj_parm.c2 * (this->m_proj_parm.c1 - tan(lp_lat)); BUG STILL IN proj (reported 2012-03-03)
break;
default:
rho = this->m_proj_parm.rho_c - lp_lat;

View File

@@ -116,9 +116,7 @@ namespace boost { namespace geometry { namespace projections
template <typename Parameters>
void setup_sterea(Parameters& par, par_sterea& proj_parm)
{
double R;
proj_parm.en = detail::gauss::gauss_ini(par.e, par.phi0, proj_parm.phic0, R);
proj_parm.sinc0 = sin(proj_parm.phic0);

View File

@@ -98,7 +98,7 @@ namespace boost { namespace geometry { namespace projections
{
xy_x = HUGE_VAL;
xy_y = HUGE_VAL;
throw proj_exception( -14 );
throw proj_exception(-14 );
return;
}
@@ -184,7 +184,7 @@ namespace boost { namespace geometry { namespace projections
{
xy_x = HUGE_VAL;
xy_y = HUGE_VAL;
throw proj_exception( -14 );
throw proj_exception(-14 );
return;
}

View File

@@ -106,7 +106,8 @@ namespace boost { namespace geometry { namespace projections
\par Projection characteristics
- Pseudocylindrical
- Spheroid
- n= q= alphi=
- no inverse
- n= q= alpha=
\par Example
\image html ex_urm5.gif
*/

View File

@@ -17,10 +17,14 @@
#include <cstddef>
#include <boost/concept/assert.hpp>
#include <boost/config.hpp>
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
#include <boost/assert.hpp>
#endif
namespace boost { namespace geometry
@@ -29,18 +33,21 @@ namespace boost { namespace geometry
namespace model
{
/*!
\brief Class box: defines a box made of two describing points
\ingroup geometries
\details Box is always described by a min_corner() and a max_corner() point. If another
rectangle is used, use linear_ring or polygon.
\note Boxes are for selections and for calculating the envelope of geometries. Not all algorithms
are implemented for box. Boxes are also used in Spatial Indexes.
\tparam Point point type. The box takes a point type as template parameter.
The point type can be any point type.
It can be 2D but can also be 3D or more dimensional.
The box can also take a latlong point type as template parameter.
\brief Class box: defines a box made of two describing points
\ingroup geometries
\details Box is always described by a min_corner() and a max_corner() point. If another
rectangle is used, use linear_ring or polygon.
\note Boxes are for selections and for calculating the envelope of geometries. Not all algorithms
are implemented for box. Boxes are also used in Spatial Indexes.
\tparam Point point type. The box takes a point type as template parameter.
The point type can be any point type.
It can be 2D but can also be 3D or more dimensional.
The box can also take a latlong point type as template parameter.
\qbk{[include reference/geometries/box.qbk]}
\qbk{before.synopsis, [heading Model of]}
\qbk{before.synopsis, [link geometry.reference.concepts.concept_box Box Concept]}
*/
template<typename Point>
@@ -50,7 +57,25 @@ class box
public:
inline box() {}
#if !defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
/// \constructor_default_no_init
box() = default;
#else
/// \constructor_default_no_init
inline box()
{}
#endif
#else // defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
inline box()
{
m_created = 1;
}
~box()
{
m_created = 0;
}
#endif
/*!
\brief Constructor taking the minimum corner point and the maximum corner point
@@ -59,18 +84,50 @@ public:
{
geometry::convert(min_corner, m_min_corner);
geometry::convert(max_corner, m_max_corner);
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
m_created = 1;
#endif
}
inline Point const& min_corner() const { return m_min_corner; }
inline Point const& max_corner() const { return m_max_corner; }
inline Point const& min_corner() const
{
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
BOOST_ASSERT(m_created == 1);
#endif
return m_min_corner;
}
inline Point const& max_corner() const
{
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
BOOST_ASSERT(m_created == 1);
#endif
return m_max_corner;
}
inline Point& min_corner() { return m_min_corner; }
inline Point& max_corner() { return m_max_corner; }
inline Point& min_corner()
{
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
BOOST_ASSERT(m_created == 1);
#endif
return m_min_corner;
}
inline Point& max_corner()
{
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
BOOST_ASSERT(m_created == 1);
#endif
return m_max_corner;
}
private:
Point m_min_corner;
Point m_max_corner;
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
int m_created;
#endif
};

View File

@@ -26,12 +26,10 @@
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#include <boost/config.hpp>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
#endif
namespace boost { namespace geometry
{
@@ -46,6 +44,7 @@ namespace model
\tparam Container \tparam_container
\tparam Allocator \tparam_allocator
\qbk{[include reference/geometries/linestring.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_linestring Linestring Concept]
@@ -76,7 +75,6 @@ public :
: base_type(begin, end)
{}
#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/// \constructor_initializer_list{linestring}
@@ -97,7 +95,6 @@ public :
// }
//#endif
#endif
#endif
};

View File

@@ -23,12 +23,10 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/linestring_concept.hpp>
#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#include <boost/config.hpp>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
#endif
namespace boost { namespace geometry
{
@@ -43,6 +41,7 @@ namespace model
e.g. a highway (with interruptions)
\ingroup geometries
\qbk{[include reference/geometries/multi_linestring.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_multi_linestring MultiLineString Concept]
@@ -58,7 +57,10 @@ class multi_linestring : public Container<LineString, Allocator<LineString> >
{
BOOST_CONCEPT_ASSERT( (concept::Linestring<LineString>) );
#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
// default constructor and base_type definitions are required only
// if the constructor taking std::initializer_list is defined
typedef Container<LineString, Allocator<LineString> > base_type;
@@ -68,8 +70,6 @@ public:
: base_type()
{}
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/// \constructor_initializer_list{multi_linestring}
inline multi_linestring(std::initializer_list<LineString> l)
: base_type(l.begin(), l.end())
@@ -88,7 +88,6 @@ public:
// }
//#endif
#endif
#endif
};

View File

@@ -23,12 +23,10 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#include <boost/config.hpp>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
#endif
namespace boost { namespace geometry
{
@@ -45,6 +43,8 @@ namespace model
\tparam Allocator \tparam_allocator
\details Multipoint can be used to group points belonging to each other,
e.g. a constellation, or the result set of an intersection
\qbk{[include reference/geometries/multi_point.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_multi_point MultiPoint Concept]
@@ -74,7 +74,6 @@ public :
: base_type(begin, end)
{}
#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/// \constructor_initializer_list{multi_point}
@@ -95,7 +94,6 @@ public :
// }
//#endif
#endif
#endif
};

View File

@@ -23,12 +23,10 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/polygon_concept.hpp>
#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#include <boost/config.hpp>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
#endif
namespace boost { namespace geometry
{
@@ -42,6 +40,7 @@ namespace model
e.g. Hawaii
\ingroup geometries
\qbk{[include reference/geometries/multi_polygon.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_multi_polygon MultiPolygon Concept]
@@ -57,7 +56,10 @@ class multi_polygon : public Container<Polygon, Allocator<Polygon> >
{
BOOST_CONCEPT_ASSERT( (concept::Polygon<Polygon>) );
#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
// default constructor and base_type definitions are required only
// if the constructor taking std::initializer_list is defined
typedef Container<Polygon, Allocator<Polygon> > base_type;
@@ -67,8 +69,6 @@ public:
: base_type()
{}
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/// \constructor_initializer_list{multi_polygon}
inline multi_polygon(std::initializer_list<Polygon> l)
: base_type(l.begin(), l.end())
@@ -87,7 +87,6 @@ public:
// }
//#endif
#endif
#endif
};

View File

@@ -22,14 +22,20 @@
#include <cstddef>
#include <boost/config.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/int.hpp>
#include <boost/static_assert.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
#include <algorithm>
#include <boost/assert.hpp>
#endif
namespace boost { namespace geometry
{
@@ -100,7 +106,10 @@ template
>
class point
{
private:
BOOST_MPL_ASSERT_MSG((DimensionCount >= 1),
DIMENSION_GREATER_THAN_ZERO_EXPECTED,
(boost::mpl::int_<DimensionCount>));
// The following enum is used to fully instantiate the
// CoordinateSystem class and check the correctness of the units
// passed for non-Cartesian coordinate systems.
@@ -108,11 +117,27 @@ private:
public:
/// @brief Default constructor, no initialization
#if !defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
/// \constructor_default_no_init
point() = default;
#else
/// \constructor_default_no_init
inline point()
{}
#endif
#else // defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
point()
{
BOOST_STATIC_ASSERT(DimensionCount >= 1);
m_created = 1;
std::fill_n(m_values_initialized, DimensionCount, 0);
}
~point()
{
m_created = 0;
std::fill_n(m_values_initialized, DimensionCount, 0);
}
#endif
/// @brief Constructor to set one value
explicit inline point(CoordinateType const& v0)
@@ -120,6 +145,11 @@ public:
detail::array_assign<DimensionCount, 0>::apply(m_values, v0);
detail::array_assign<DimensionCount, 1>::apply(m_values, CoordinateType());
detail::array_assign<DimensionCount, 2>::apply(m_values, CoordinateType());
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
m_created = 1;
std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1);
#endif
}
/// @brief Constructor to set two values
@@ -128,6 +158,11 @@ public:
detail::array_assign<DimensionCount, 0>::apply(m_values, v0);
detail::array_assign<DimensionCount, 1>::apply(m_values, v1);
detail::array_assign<DimensionCount, 2>::apply(m_values, CoordinateType());
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
m_created = 1;
std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1);
#endif
}
/// @brief Constructor to set three values
@@ -137,6 +172,11 @@ public:
detail::array_assign<DimensionCount, 0>::apply(m_values, v0);
detail::array_assign<DimensionCount, 1>::apply(m_values, v1);
detail::array_assign<DimensionCount, 2>::apply(m_values, v2);
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
m_created = 1;
std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1);
#endif
}
/// @brief Get a coordinate
@@ -145,6 +185,10 @@ public:
template <std::size_t K>
inline CoordinateType const& get() const
{
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
BOOST_ASSERT(m_created == 1);
BOOST_ASSERT(m_values_initialized[K] == 1);
#endif
BOOST_STATIC_ASSERT(K < DimensionCount);
return m_values[K];
}
@@ -155,6 +199,10 @@ public:
template <std::size_t K>
inline void set(CoordinateType const& value)
{
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
BOOST_ASSERT(m_created == 1);
m_values_initialized[K] = 1;
#endif
BOOST_STATIC_ASSERT(K < DimensionCount);
m_values[K] = value;
}
@@ -162,6 +210,11 @@ public:
private:
CoordinateType m_values[DimensionCount];
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
int m_created;
int m_values_initialized[DimensionCount];
#endif
};

View File

@@ -16,6 +16,7 @@
#include <cstddef>
#include <boost/config.hpp>
#include <boost/mpl/int.hpp>
#include <boost/geometry/core/cs.hpp>
@@ -32,6 +33,7 @@ namespace model { namespace d2
\tparam CoordinateType numeric type, for example, double, float, int
\tparam CoordinateSystem coordinate system, defaults to cs::cartesian
\qbk{[include reference/geometries/point_xy.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_point Point Concept]
@@ -45,10 +47,14 @@ class point_xy : public model::point<CoordinateType, 2, CoordinateSystem>
{
public:
/// Default constructor, does not initialize anything
#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
/// \constructor_default_no_init
point_xy() = default;
#else
/// \constructor_default_no_init
inline point_xy()
: model::point<CoordinateType, 2, CoordinateSystem>()
{}
#endif
/// Constructor with x/y values
inline point_xy(CoordinateType const& x, CoordinateType const& y)

View File

@@ -27,12 +27,10 @@
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#include <boost/geometry/geometries/ring.hpp>
#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#include <boost/config.hpp>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
#endif
namespace boost { namespace geometry
{
@@ -57,6 +55,7 @@ namespace model
\note The container collecting the points in the rings can be different
from the container collecting the inner rings. They all default to vector.
\qbk{[include reference/geometries/polygon.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_polygon Polygon Concept]
@@ -91,7 +90,10 @@ public:
inline ring_type& outer() { return m_outer; }
inline inner_container_type & inners() { return m_inners; }
#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
// default constructor definition is required only
// if the constructor taking std::initializer_list is defined
/// \constructor_default{polygon}
inline polygon()
@@ -99,7 +101,6 @@ public:
, m_inners()
{}
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/// \constructor_initializer_list{polygon}
inline polygon(std::initializer_list<ring_type> l)
: m_outer(l.size() > 0 ? *l.begin() : ring_type())
@@ -128,7 +129,6 @@ public:
// }
//#endif
#endif
#endif
/// Utility method, clears outer and inner rings

View File

@@ -27,12 +27,10 @@
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#include <boost/config.hpp>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
#endif
namespace boost { namespace geometry
{
@@ -50,6 +48,7 @@ namespace model
\tparam Container container type, for example std::vector, std::deque
\tparam Allocator container-allocator-type
\qbk{[include reference/geometries/ring.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_ring Ring Concept]
@@ -80,7 +79,6 @@ public :
: base_type(begin, end)
{}
#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/// \constructor_initializer_list{ring}
@@ -101,7 +99,6 @@ public :
// }
//#endif
#endif
#endif
};

View File

@@ -35,14 +35,32 @@ namespace model
by two distinct end points, and contains every point on the line between its end points.
\note There is also a point-referring-segment, class referring_segment,
containing point references, where points are NOT copied
\qbk{[include reference/geometries/segment.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_segment Segment Concept]
}
*/
template<typename Point>
class segment : public std::pair<Point, Point>
{
BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
public :
#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
/// \constructor_default_no_init
segment() = default;
#else
/// \constructor_default_no_init
inline segment()
{}
#endif
/*!
\brief Constructor taking the first and the second point
*/
inline segment(Point const& p1, Point const& p2)
{
this->first = p1;
@@ -83,6 +101,9 @@ public:
point_type& first;
point_type& second;
/*!
\brief Constructor taking the first and the second point
*/
inline referring_segment(point_type& p1, point_type& p2)
: first(p1)
, second(p2)

View File

@@ -90,10 +90,6 @@
#include <boost/geometry/algorithms/unique.hpp>
#include <boost/geometry/algorithms/within.hpp>
// Include multi a.o. because it can give weird effects
// if you don't (e.g. area=0 of a multipolygon)
#include <boost/geometry/multi/multi.hpp>
// check includes all concepts
#include <boost/geometry/geometries/concepts/check.hpp>

View File

@@ -3,7 +3,7 @@
// Spatial index distance predicates, calculators and checkers
// used in nearest query - specialized for envelopes
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -104,13 +104,13 @@ struct calculate_distance
// this handles nearest() with default Point parameter, to_nearest() and bounds
template <typename PointRelation, typename Indexable, typename Tag>
struct calculate_distance< nearest<PointRelation>, Indexable, Tag >
struct calculate_distance< predicates::nearest<PointRelation>, Indexable, Tag >
{
typedef detail::relation<PointRelation> relation;
typedef typename relation::value_type point_type;
typedef typename geometry::default_comparable_distance_result<point_type, Indexable>::type result_type;
static inline bool apply(nearest<PointRelation> const& p, Indexable const& i, result_type & result)
static inline bool apply(predicates::nearest<PointRelation> const& p, Indexable const& i, result_type & result)
{
result = geometry::comparable_distance(relation::value(p.point_or_relation), i);
return true;
@@ -118,12 +118,12 @@ struct calculate_distance< nearest<PointRelation>, Indexable, Tag >
};
template <typename Point, typename Indexable>
struct calculate_distance< nearest< to_centroid<Point> >, Indexable, value_tag>
struct calculate_distance< predicates::nearest< to_centroid<Point> >, Indexable, value_tag>
{
typedef Point point_type;
typedef typename geometry::default_comparable_distance_result<point_type, Indexable>::type result_type;
static inline bool apply(nearest< to_centroid<Point> > const& p, Indexable const& i, result_type & result)
static inline bool apply(predicates::nearest< to_centroid<Point> > const& p, Indexable const& i, result_type & result)
{
result = index::detail::comparable_distance_centroid(p.point_or_relation.value, i);
return true;
@@ -131,12 +131,12 @@ struct calculate_distance< nearest< to_centroid<Point> >, Indexable, value_tag>
};
template <typename Point, typename Indexable>
struct calculate_distance< nearest< to_furthest<Point> >, Indexable, value_tag>
struct calculate_distance< predicates::nearest< to_furthest<Point> >, Indexable, value_tag>
{
typedef Point point_type;
typedef typename geometry::default_comparable_distance_result<point_type, Indexable>::type result_type;
static inline bool apply(nearest< to_furthest<Point> > const& p, Indexable const& i, result_type & result)
static inline bool apply(predicates::nearest< to_furthest<Point> > const& p, Indexable const& i, result_type & result)
{
result = index::detail::comparable_distance_far(p.point_or_relation.value, i);
return true;
@@ -144,13 +144,13 @@ struct calculate_distance< nearest< to_furthest<Point> >, Indexable, value_tag>
};
template <typename SegmentOrLinestring, typename Indexable, typename Tag>
struct calculate_distance< path<SegmentOrLinestring>, Indexable, Tag>
struct calculate_distance< predicates::path<SegmentOrLinestring>, Indexable, Tag>
{
typedef typename index::detail::default_path_intersection_distance_type<
Indexable, SegmentOrLinestring
>::type result_type;
static inline bool apply(path<SegmentOrLinestring> const& p, Indexable const& i, result_type & result)
static inline bool apply(predicates::path<SegmentOrLinestring> const& p, Indexable const& i, result_type & result)
{
return index::detail::path_intersection(i, p.geometry, result);
}

View File

@@ -2,7 +2,7 @@
//
// Spatial query predicates definition and checks.
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -16,6 +16,8 @@
namespace boost { namespace geometry { namespace index { namespace detail {
namespace predicates {
// ------------------------------------------------------------------ //
// predicates
// ------------------------------------------------------------------ //
@@ -23,6 +25,7 @@ namespace boost { namespace geometry { namespace index { namespace detail {
template <typename Fun, bool IsFunction>
struct satisfies_impl
{
satisfies_impl() : fun(NULL) {}
satisfies_impl(Fun f) : fun(f) {}
Fun * fun;
};
@@ -30,6 +33,7 @@ struct satisfies_impl
template <typename Fun>
struct satisfies_impl<Fun, false>
{
satisfies_impl() {}
satisfies_impl(Fun const& f) : fun(f) {}
Fun fun;
};
@@ -40,6 +44,7 @@ struct satisfies
{
typedef satisfies_impl<Fun, ::boost::is_function<Fun>::value> base;
satisfies() {}
satisfies(Fun const& f) : base(f) {}
satisfies(base const& b) : base(b) {}
};
@@ -58,6 +63,7 @@ struct within_tag {};
template <typename Geometry, typename Tag, bool Negated>
struct spatial_predicate
{
spatial_predicate() {}
spatial_predicate(Geometry const& g) : geometry(g) {}
Geometry geometry;
};
@@ -73,6 +79,9 @@ struct spatial_predicate
template <typename PointOrRelation>
struct nearest
{
nearest()
// : count(0)
{}
nearest(PointOrRelation const& por, unsigned k)
: point_or_relation(por)
, count(k)
@@ -84,6 +93,9 @@ struct nearest
template <typename SegmentOrLinestring>
struct path
{
path()
// : count(0)
{}
path(SegmentOrLinestring const& g, unsigned k)
: geometry(g)
, count(k)
@@ -92,6 +104,8 @@ struct path
unsigned count;
};
} // namespace predicates
// ------------------------------------------------------------------ //
// predicate_check
// ------------------------------------------------------------------ //
@@ -108,20 +122,20 @@ struct predicate_check
// ------------------------------------------------------------------ //
template <typename Fun>
struct predicate_check<satisfies<Fun, false>, value_tag>
struct predicate_check<predicates::satisfies<Fun, false>, value_tag>
{
template <typename Value, typename Indexable>
static inline bool apply(satisfies<Fun, false> const& p, Value const& v, Indexable const&)
static inline bool apply(predicates::satisfies<Fun, false> const& p, Value const& v, Indexable const&)
{
return p.fun(v);
}
};
template <typename Fun>
struct predicate_check<satisfies<Fun, true>, value_tag>
struct predicate_check<predicates::satisfies<Fun, true>, value_tag>
{
template <typename Value, typename Indexable>
static inline bool apply(satisfies<Fun, true> const& p, Value const& v, Indexable const&)
static inline bool apply(predicates::satisfies<Fun, true> const& p, Value const& v, Indexable const&)
{
return !p.fun(v);
}
@@ -136,7 +150,7 @@ struct spatial_predicate_call
};
template <>
struct spatial_predicate_call<contains_tag>
struct spatial_predicate_call<predicates::contains_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
@@ -146,7 +160,7 @@ struct spatial_predicate_call<contains_tag>
};
template <>
struct spatial_predicate_call<covered_by_tag>
struct spatial_predicate_call<predicates::covered_by_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
@@ -156,7 +170,7 @@ struct spatial_predicate_call<covered_by_tag>
};
template <>
struct spatial_predicate_call<covers_tag>
struct spatial_predicate_call<predicates::covers_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
@@ -166,7 +180,7 @@ struct spatial_predicate_call<covers_tag>
};
template <>
struct spatial_predicate_call<disjoint_tag>
struct spatial_predicate_call<predicates::disjoint_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
@@ -176,7 +190,7 @@ struct spatial_predicate_call<disjoint_tag>
};
template <>
struct spatial_predicate_call<intersects_tag>
struct spatial_predicate_call<predicates::intersects_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
@@ -186,7 +200,7 @@ struct spatial_predicate_call<intersects_tag>
};
template <>
struct spatial_predicate_call<overlaps_tag>
struct spatial_predicate_call<predicates::overlaps_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
@@ -196,7 +210,7 @@ struct spatial_predicate_call<overlaps_tag>
};
template <>
struct spatial_predicate_call<touches_tag>
struct spatial_predicate_call<predicates::touches_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
@@ -206,7 +220,7 @@ struct spatial_predicate_call<touches_tag>
};
template <>
struct spatial_predicate_call<within_tag>
struct spatial_predicate_call<predicates::within_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
@@ -219,9 +233,9 @@ struct spatial_predicate_call<within_tag>
// spatial predicate
template <typename Geometry, typename Tag>
struct predicate_check<spatial_predicate<Geometry, Tag, false>, value_tag>
struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, value_tag>
{
typedef spatial_predicate<Geometry, Tag, false> Pred;
typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
@@ -232,9 +246,9 @@ struct predicate_check<spatial_predicate<Geometry, Tag, false>, value_tag>
// negated spatial predicate
template <typename Geometry, typename Tag>
struct predicate_check<spatial_predicate<Geometry, Tag, true>, value_tag>
struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, value_tag>
{
typedef spatial_predicate<Geometry, Tag, true> Pred;
typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
@@ -246,20 +260,20 @@ struct predicate_check<spatial_predicate<Geometry, Tag, true>, value_tag>
// ------------------------------------------------------------------ //
template <typename DistancePredicates>
struct predicate_check<nearest<DistancePredicates>, value_tag>
struct predicate_check<predicates::nearest<DistancePredicates>, value_tag>
{
template <typename Value, typename Box>
static inline bool apply(nearest<DistancePredicates> const&, Value const&, Box const&)
static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&)
{
return true;
}
};
template <typename Linestring>
struct predicate_check<path<Linestring>, value_tag>
struct predicate_check<predicates::path<Linestring>, value_tag>
{
template <typename Value, typename Box>
static inline bool apply(path<Linestring> const&, Value const&, Box const&)
static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&)
{
return true;
}
@@ -270,10 +284,10 @@ struct predicate_check<path<Linestring>, value_tag>
// ------------------------------------------------------------------ //
template <typename Fun, bool Negated>
struct predicate_check<satisfies<Fun, Negated>, bounds_tag>
struct predicate_check<predicates::satisfies<Fun, Negated>, bounds_tag>
{
template <typename Value, typename Box>
static bool apply(satisfies<Fun, Negated> const&, Value const&, Box const&)
static bool apply(predicates::satisfies<Fun, Negated> const&, Value const&, Box const&)
{
return true;
}
@@ -295,53 +309,53 @@ struct predicate_check<satisfies<Fun, Negated>, bounds_tag>
// spatial predicate - default
template <typename Geometry, typename Tag>
struct predicate_check<spatial_predicate<Geometry, Tag, false>, bounds_tag>
struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, bounds_tag>
{
typedef spatial_predicate<Geometry, Tag, false> Pred;
typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
return spatial_predicate_call<intersects_tag>::apply(i, p.geometry);
return spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry);
}
};
// spatial predicate - contains
template <typename Geometry>
struct predicate_check<spatial_predicate<Geometry, contains_tag, false>, bounds_tag>
struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, false>, bounds_tag>
{
typedef spatial_predicate<Geometry, contains_tag, false> Pred;
typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, false> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
return spatial_predicate_call<contains_tag>::apply(i, p.geometry);
return spatial_predicate_call<predicates::contains_tag>::apply(i, p.geometry);
}
};
// spatial predicate - covers
template <typename Geometry>
struct predicate_check<spatial_predicate<Geometry, covers_tag, false>, bounds_tag>
struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, false>, bounds_tag>
{
typedef spatial_predicate<Geometry, covers_tag, false> Pred;
typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, false> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
return spatial_predicate_call<covers_tag>::apply(i, p.geometry);
return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry);
}
};
// spatial predicate - disjoint
template <typename Geometry>
struct predicate_check<spatial_predicate<Geometry, disjoint_tag, false>, bounds_tag>
struct predicate_check<predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false>, bounds_tag>
{
typedef spatial_predicate<Geometry, disjoint_tag, false> Pred;
typedef predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
return !spatial_predicate_call<covered_by_tag>::apply(i, p.geometry);
return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry);
}
};
@@ -359,9 +373,9 @@ struct predicate_check<spatial_predicate<Geometry, disjoint_tag, false>, bounds_
// negated spatial predicate - default
template <typename Geometry, typename Tag>
struct predicate_check<spatial_predicate<Geometry, Tag, true>, bounds_tag>
struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, bounds_tag>
{
typedef spatial_predicate<Geometry, Tag, true> Pred;
typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
@@ -372,9 +386,9 @@ struct predicate_check<spatial_predicate<Geometry, Tag, true>, bounds_tag>
// negated spatial predicate - contains
template <typename Geometry>
struct predicate_check<spatial_predicate<Geometry, contains_tag, true>, bounds_tag>
struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, true>, bounds_tag>
{
typedef spatial_predicate<Geometry, contains_tag, true> Pred;
typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& , Value const&, Indexable const& )
@@ -385,9 +399,9 @@ struct predicate_check<spatial_predicate<Geometry, contains_tag, true>, bounds_t
// negated spatial predicate - covers
template <typename Geometry>
struct predicate_check<spatial_predicate<Geometry, covers_tag, true>, bounds_tag>
struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, true>, bounds_tag>
{
typedef spatial_predicate<Geometry, covers_tag, true> Pred;
typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& , Value const&, Indexable const& )
@@ -398,22 +412,22 @@ struct predicate_check<spatial_predicate<Geometry, covers_tag, true>, bounds_tag
// negated spatial predicate - intersects
template <typename Geometry>
struct predicate_check<spatial_predicate<Geometry, intersects_tag, true>, bounds_tag>
struct predicate_check<predicates::spatial_predicate<Geometry, predicates::intersects_tag, true>, bounds_tag>
{
typedef spatial_predicate<Geometry, intersects_tag, true> Pred;
typedef predicates::spatial_predicate<Geometry, predicates::intersects_tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
return !spatial_predicate_call<covered_by_tag>::apply(i, p.geometry);
return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry);
}
};
// negated spatial predicate - overlaps
template <typename Geometry>
struct predicate_check<spatial_predicate<Geometry, overlaps_tag, true>, bounds_tag>
struct predicate_check<predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true>, bounds_tag>
{
typedef spatial_predicate<Geometry, overlaps_tag, true> Pred;
typedef predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& , Value const&, Indexable const& )
@@ -424,34 +438,34 @@ struct predicate_check<spatial_predicate<Geometry, overlaps_tag, true>, bounds_t
// negated spatial predicate - touches
template <typename Geometry>
struct predicate_check<spatial_predicate<Geometry, touches_tag, true>, bounds_tag>
struct predicate_check<predicates::spatial_predicate<Geometry, predicates::touches_tag, true>, bounds_tag>
{
typedef spatial_predicate<Geometry, touches_tag, true> Pred;
typedef predicates::spatial_predicate<Geometry, predicates::touches_tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
return !spatial_predicate_call<intersects_tag>::apply(i, p.geometry);
return !spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry);
}
};
// ------------------------------------------------------------------ //
template <typename DistancePredicates>
struct predicate_check<nearest<DistancePredicates>, bounds_tag>
struct predicate_check<predicates::nearest<DistancePredicates>, bounds_tag>
{
template <typename Value, typename Box>
static inline bool apply(nearest<DistancePredicates> const&, Value const&, Box const&)
static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&)
{
return true;
}
};
template <typename Linestring>
struct predicate_check<path<Linestring>, bounds_tag>
struct predicate_check<predicates::path<Linestring>, bounds_tag>
{
template <typename Value, typename Box>
static inline bool apply(path<Linestring> const&, Value const&, Box const&)
static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&)
{
return true;
}
@@ -697,13 +711,13 @@ struct predicates_is_distance
};
template <typename DistancePredicates>
struct predicates_is_distance< nearest<DistancePredicates> >
struct predicates_is_distance< predicates::nearest<DistancePredicates> >
{
static const unsigned value = 1;
};
template <typename Linestring>
struct predicates_is_distance< path<Linestring> >
struct predicates_is_distance< predicates::path<Linestring> >
{
static const unsigned value = 1;
};

View File

@@ -0,0 +1,122 @@
// Boost.Geometry Index
//
// R-tree iterators
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
template <typename Value, typename Allocators>
struct end_iterator
{
typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
reference operator*() const
{
BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not dereferencable");
pointer p(0);
return *p;
}
const value_type * operator->() const
{
BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not dereferencable");
const value_type * p = 0;
return p;
}
end_iterator & operator++()
{
BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not incrementable");
return *this;
}
end_iterator operator++(int)
{
BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not incrementable");
return *this;
}
friend bool operator==(end_iterator const& /*l*/, end_iterator const& /*r*/)
{
return true;
}
};
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
class iterator
{
typedef visitors::iterator<Value, Options, Translator, Box, Allocators> visitor_type;
typedef typename visitor_type::node_pointer node_pointer;
public:
typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
inline iterator()
{}
inline iterator(node_pointer root)
{
m_visitor.initialize(root);
}
reference operator*() const
{
return m_visitor.dereference();
}
const value_type * operator->() const
{
return boost::addressof(m_visitor.dereference());
}
iterator & operator++()
{
m_visitor.increment();
return *this;
}
iterator operator++(int)
{
iterator temp = *this;
this->operator++();
return temp;
}
friend bool operator==(iterator const& l, iterator const& r)
{
return l.m_visitor == r.m_visitor;
}
friend bool operator==(iterator const& l, end_iterator<Value, Allocators> const& /*r*/)
{
return l.m_visitor.is_end();
}
friend bool operator==(end_iterator<Value, Allocators> const& /*l*/, iterator const& r)
{
return r.m_visitor.is_end();
}
private:
visitor_type m_visitor;
};
}}}}}} // namespace boost::geometry::index::detail::rtree::iterators
#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP

View File

@@ -1,38 +0,0 @@
// Boost.Geometry Index
//
// R-tree auto deallocator
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_AUTO_DEALLOCATOR_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_AUTO_DEALLOCATOR_HPP
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
template <typename Alloc>
class auto_deallocator
{
auto_deallocator(auto_deallocator const&);
auto_deallocator & operator=(auto_deallocator const&);
public:
typedef typename Alloc::pointer pointer;
inline auto_deallocator(Alloc & a, pointer p) : m_alloc(a), m_ptr(p) {}
inline ~auto_deallocator() { if ( m_ptr ) boost::container::allocator_traits<Alloc>::deallocate(m_alloc, m_ptr, 1); }
inline void release() { m_ptr = 0; }
inline pointer ptr() { return m_ptr; }
private:
Alloc & m_alloc;
pointer m_ptr;
};
}} // namespace detail::rtree
}}} // namespace boost::geometry::index
#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_AUTO_DEALLOCATOR_HPP

View File

@@ -2,7 +2,7 @@
//
// R-tree nodes
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -16,8 +16,8 @@
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
#include <boost/geometry/index/detail/rtree/node/pairs.hpp>
#include <boost/geometry/index/detail/rtree/node/auto_deallocator.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/scoped_deallocator.hpp>
//#include <boost/geometry/index/detail/rtree/node/weak_visitor.hpp>
//#include <boost/geometry/index/detail/rtree/node/weak_dynamic.hpp>
@@ -27,7 +27,7 @@
#include <boost/geometry/index/detail/rtree/node/variant_dynamic.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_static.hpp>
#include <boost/geometry/index/detail/rtree/node/node_auto_ptr.hpp>
#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
#include <boost/geometry/algorithms/expand.hpp>
@@ -70,11 +70,11 @@ struct destroy_element
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
inline static void apply(typename internal_node::elements_type::value_type & element, Allocators & allocators)
{
node_auto_ptr dummy(element.second, allocators);
subtree_destroyer dummy(element.second, allocators);
element.second = 0;
}
@@ -108,11 +108,11 @@ private:
inline static void apply_dispatch(It first, It last, Allocators & allocators,
boost::mpl::bool_<false> const& /*is_range_of_values*/)
{
typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
for ( ; first != last ; ++first )
{
node_auto_ptr dummy(first->second, allocators);
subtree_destroyer dummy(first->second, allocators);
first->second = 0;
}
}

View File

@@ -0,0 +1,48 @@
// Boost.Geometry Index
//
// R-tree scoped deallocator
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SCOPED_DEALLOCATOR_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SCOPED_DEALLOCATOR_HPP
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
template <typename Alloc>
class scoped_deallocator
{
scoped_deallocator(scoped_deallocator const&);
scoped_deallocator & operator=(scoped_deallocator const&);
public:
typedef typename Alloc::pointer pointer;
inline scoped_deallocator(pointer p, Alloc & a)
: m_ptr(p), m_alloc(a)
{}
inline ~scoped_deallocator()
{
if ( m_ptr )
{
boost::container::allocator_traits<Alloc>::deallocate(m_alloc, m_ptr, 1);
}
}
inline void release()
{
m_ptr = 0;
}
private:
pointer m_ptr;
Alloc & m_alloc;
};
}} // namespace detail::rtree
}}} // namespace boost::geometry::index
#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SCOPED_DEALLOCATOR_HPP

View File

@@ -1,15 +1,15 @@
// Boost.Geometry Index
//
// R-tree node auto ptr
// R-tree subtree scoped destroyer
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_AUTO_PTR_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_AUTO_PTR_HPP
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SUBTREE_DESTROYED_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SUBTREE_DESTROYED_HPP
#include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
@@ -17,31 +17,29 @@ namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
// TODO - change the name to node_scoped_ptr
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
class node_auto_ptr
class subtree_destroyer
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename Allocators::node_pointer pointer;
node_auto_ptr(node_auto_ptr const&);
node_auto_ptr & operator=(node_auto_ptr const&);
subtree_destroyer(subtree_destroyer const&);
subtree_destroyer & operator=(subtree_destroyer const&);
public:
node_auto_ptr(pointer ptr, Allocators & allocators)
subtree_destroyer(pointer ptr, Allocators & allocators)
: m_ptr(ptr)
, m_allocators(allocators)
{}
~node_auto_ptr()
~subtree_destroyer()
{
reset();
}
void reset(pointer ptr = 0)
{
if ( m_ptr )
if ( m_ptr && m_ptr != ptr )
{
detail::rtree::visitors::destroy<Value, Options, Translator, Box, Allocators> del_v(m_ptr, m_allocators);
detail::rtree::apply_visitor(del_v, *m_ptr);
@@ -78,4 +76,4 @@ private:
}}} // namespace boost::geometry::index
#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_AUTO_PTR_HPP
#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SUBTREE_DESTROYED_HPP

View File

@@ -181,7 +181,7 @@ struct create_variant_node
if ( 0 == p )
throw_runtime_error("boost::geometry::index::rtree node creation failed");
auto_deallocator<AllocNode> deallocator(alloc_node, p);
scoped_deallocator<AllocNode> deallocator(p, alloc_node);
Al::construct(alloc_node, boost::addressof(*p), Node(alloc_node)); // implicit cast to Variant

View File

@@ -197,7 +197,7 @@ struct create_weak_node
if ( 0 == p )
throw_runtime_error("boost::geometry::index::rtree node creation failed");
auto_deallocator<AllocNode> deallocator(alloc_node, p);
scoped_deallocator<AllocNode> deallocator(p, alloc_node);
Al::construct(alloc_node, boost::addressof(*p), alloc_node);

View File

@@ -2,7 +2,7 @@
//
// R-tree initial packing
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -122,7 +122,7 @@ class pack
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename Allocators::node_pointer node_pointer;
typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::size_type size_type;
typedef typename geometry::point_type<Box>::type point_type;
@@ -161,7 +161,12 @@ public:
geometry::assign_inverse(hint_box);
for ( ; first != last ; ++first )
{
typename Translator::result_type indexable = translator(*first);
// NOTE: support for iterators not returning true references adapted
// to Geometry concept and default translator returning true reference
// An alternative would be to dereference the iterator and translate
// in one expression each time the indexable was needed.
typename std::iterator_traits<InIt>::reference in_ref = *first;
typename Translator::result_type indexable = translator(in_ref);
// NOTE: added for consistency with insert()
// CONSIDER: alternative - ignore invalid indexable or throw an exception
@@ -205,7 +210,7 @@ private:
// create new leaf node
node_pointer n = rtree::create_node<Allocators, leaf>::apply(allocators); // MAY THROW (A)
node_auto_ptr auto_remover(n, allocators);
subtree_destroyer auto_remover(n, allocators);
leaf & l = rtree::get<leaf>(*n);
// reserve space for values
@@ -215,8 +220,11 @@ private:
geometry::assign_inverse(elements_box);
for ( ; first != last ; ++first )
{
rtree::elements(l).push_back(*(first->second)); // MAY THROW (A?,C)
// NOTE: push_back() must be called at the end in order to support move_iterator.
// The iterator is dereferenced 2x (no temporary reference) to support
// non-true reference types and move_iterator without boost::forward<>.
geometry::expand(elements_box, translator(*(first->second)));
rtree::elements(l).push_back(*(first->second)); // MAY THROW (A?,C)
}
auto_remover.release();
@@ -230,7 +238,7 @@ private:
// create new internal node
node_pointer n = rtree::create_node<Allocators, internal_node>::apply(allocators); // MAY THROW (A)
node_auto_ptr auto_remover(n, allocators);
subtree_destroyer auto_remover(n, allocators);
internal_node & in = rtree::get<internal_node>(*n);
// reserve space for values
@@ -272,7 +280,7 @@ private:
// in case if push_back() do throw here
// and even if this is not probable (previously reserved memory, nonthrowing pairs copy)
// this case is also tested by exceptions test.
node_auto_ptr auto_remover(el.second, allocators);
subtree_destroyer auto_remover(el.second, allocators);
// this container should have memory allocated, reserve() called outside
elements.push_back(el); // MAY THROW (A?,C) - however in normal conditions shouldn't
auto_remover.release();

View File

@@ -11,6 +11,8 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_QUERY_ITERATORS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_QUERY_ITERATORS_HPP
#include <boost/scoped_ptr.hpp>
//#define BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
@@ -18,7 +20,7 @@ namespace boost { namespace geometry { namespace index { namespace detail { name
template <typename Value, typename Allocators>
struct end_query_iterator
{
typedef std::input_iterator_tag iterator_category;
typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
@@ -63,12 +65,15 @@ class spatial_query_iterator
typedef typename visitor_type::node_pointer node_pointer;
public:
typedef std::input_iterator_tag iterator_category;
typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
inline spatial_query_iterator()
{}
inline spatial_query_iterator(Translator const& t, Predicates const& p)
: m_visitor(t, p)
{}
@@ -128,12 +133,15 @@ class distance_query_iterator
typedef typename visitor_type::node_pointer node_pointer;
public:
typedef std::input_iterator_tag iterator_category;
typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
inline distance_query_iterator()
{}
inline distance_query_iterator(Translator const& t, Predicates const& p)
: m_visitor(t, p)
{}
@@ -186,22 +194,19 @@ private:
visitor_type m_visitor;
};
template <typename L, typename R>
inline bool operator!=(L const& l, R const& r)
{
return !(l == r);
}
}}}}}} // namespace boost::geometry::index::detail::rtree::iterators
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
template <typename Value, typename Allocators>
class query_iterator_base
{
public:
typedef std::input_iterator_tag iterator_category;
typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
@@ -224,12 +229,13 @@ class query_iterator_wrapper
typedef query_iterator_base<Value, Allocators> base_t;
public:
typedef std::input_iterator_tag iterator_category;
typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
query_iterator_wrapper() : m_iterator() {}
explicit query_iterator_wrapper(Iterator const& it) : m_iterator(it) {}
virtual base_t * clone() const { return new query_iterator_wrapper(m_iterator); }
@@ -253,16 +259,17 @@ template <typename Value, typename Allocators>
class query_iterator
{
typedef query_iterator_base<Value, Allocators> iterator_base;
typedef std::auto_ptr<iterator_base> iterator_ptr;
typedef boost::scoped_ptr<iterator_base> iterator_ptr;
public:
typedef std::input_iterator_tag iterator_category;
typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
query_iterator() {}
query_iterator()
{}
template <typename It>
query_iterator(It const& it)
@@ -280,21 +287,24 @@ public:
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
query_iterator & operator=(query_iterator const& o)
{
m_ptr.reset(o.m_ptr.get() ? o.m_ptr->clone() : 0);
if ( this != boost::addressof(o) )
{
m_ptr.reset(o.m_ptr.get() ? o.m_ptr->clone() : 0);
}
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
query_iterator(query_iterator && o)
: m_ptr(o.m_ptr.get())
: m_ptr(0)
{
o.m_ptr.release();
m_ptr.swap(o.m_ptr);
}
query_iterator & operator=(query_iterator && o)
{
if ( this != boost::addressof(o) )
{
m_ptr.reset(o.m_ptr.get());
o.m_ptr.release();
m_ptr.swap(o.m_ptr);
o.m_ptr.reset();
}
return *this;
}
@@ -305,20 +315,23 @@ private:
public:
query_iterator & operator=(BOOST_COPY_ASSIGN_REF(query_iterator) o)
{
m_ptr.reset(o.m_ptr.get() ? o.m_ptr->clone() : 0);
if ( this != boost::addressof(o) )
{
m_ptr.reset(o.m_ptr.get() ? o.m_ptr->clone() : 0);
}
return *this;
}
query_iterator(BOOST_RV_REF(query_iterator) o)
: m_ptr(o.m_ptr.get())
: m_ptr(0)
{
o.m_ptr.release();
m_ptr.swap(o.m_ptr);
}
query_iterator & operator=(BOOST_RV_REF(query_iterator) o)
{
if ( this != boost::addressof(o) )
{
m_ptr.reset(o.m_ptr.get());
o.m_ptr.release();
m_ptr.swap(o.m_ptr);
o.m_ptr.reset();
}
return *this;
}

View File

@@ -2,7 +2,7 @@
//
// R-tree deep copying visitor implementation
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -24,7 +24,7 @@ public:
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::node_pointer node_pointer;
explicit inline copy(Allocators & allocators)
@@ -35,7 +35,7 @@ public:
inline void operator()(internal_node & n)
{
node_pointer raw_new_node = rtree::create_node<Allocators, internal_node>::apply(m_allocators); // MAY THROW, STRONG (N: alloc)
node_auto_ptr new_node(raw_new_node, m_allocators);
subtree_destroyer new_node(raw_new_node, m_allocators);
typedef typename rtree::elements_type<internal_node>::type elements_type;
elements_type & elements = rtree::elements(n);
@@ -48,7 +48,7 @@ public:
rtree::apply_visitor(*this, *it->second); // MAY THROW (V, E: alloc, copy, N: alloc)
// for exception safety
node_auto_ptr auto_result(result, m_allocators);
subtree_destroyer auto_result(result, m_allocators);
elements_dst.push_back( rtree::make_ptr_pair(it->first, result) ); // MAY THROW, STRONG (E: alloc, copy)
@@ -62,7 +62,7 @@ public:
inline void operator()(leaf & l)
{
node_pointer raw_new_node = rtree::create_node<Allocators, leaf>::apply(m_allocators); // MAY THROW, STRONG (N: alloc)
node_auto_ptr new_node(raw_new_node, m_allocators);
subtree_destroyer new_node(raw_new_node, m_allocators);
typedef typename rtree::elements_type<leaf>::type elements_type;
elements_type & elements = rtree::elements(l);

View File

@@ -337,6 +337,13 @@ public:
};
typedef std::vector<internal_stack_element> internal_stack_type;
inline distance_query_incremental()
: m_translator(NULL)
// , m_pred()
, current_neighbor((std::numeric_limits<size_type>::max)())
// , next_closest_node_distance((std::numeric_limits<node_distance_type>::max)())
{}
inline distance_query_incremental(Translator const& translator, Predicates const& pred)
: m_translator(::boost::addressof(translator))
, m_pred(pred)
@@ -428,6 +435,7 @@ public:
{
BOOST_GEOMETRY_INDEX_ASSERT(l.current_neighbor != r.current_neighbor ||
(std::numeric_limits<size_type>::max)() == l.current_neighbor ||
(std::numeric_limits<size_type>::max)() == r.current_neighbor ||
l.neighbors[l.current_neighbor].second == r.neighbors[r.current_neighbor].second,
"not corresponding iterators");
return l.current_neighbor == r.current_neighbor;

View File

@@ -2,7 +2,7 @@
//
// R-tree inserting visitor implementation
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -115,7 +115,7 @@ protected:
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
public:
typedef index::detail::varray<
@@ -133,8 +133,8 @@ public:
{
// TODO - consider creating nodes always with sufficient memory allocated
// create additional node, use auto ptr for automatic destruction on exception
node_auto_ptr second_node(rtree::create_node<Allocators, Node>::apply(allocators), allocators); // MAY THROW, STRONG (N: alloc)
// create additional node, use auto destroyer for automatic destruction on exception
subtree_destroyer second_node(rtree::create_node<Allocators, Node>::apply(allocators), allocators); // MAY THROW, STRONG (N: alloc)
// create reference to the newly created node
Node & n2 = rtree::get<Node>(*second_node);
@@ -232,7 +232,7 @@ protected:
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::node_pointer node_pointer;
typedef typename Allocators::size_type size_type;
@@ -340,7 +340,7 @@ protected:
// Implement template <node_tag> struct node_element_type or something like that
// for exception safety
node_auto_ptr additional_node_ptr(additional_nodes[0].second, m_allocators);
subtree_destroyer additional_node_ptr(additional_nodes[0].second, m_allocators);
// node is not the root - just add the new node
if ( !m_traverse_data.current_is_root() )
@@ -356,7 +356,7 @@ protected:
BOOST_GEOMETRY_INDEX_ASSERT(&n == &rtree::get<Node>(*m_root_node), "node should be the root");
// create new root and add nodes
node_auto_ptr new_root(rtree::create_node<Allocators, internal_node>::apply(m_allocators), m_allocators); // MAY THROW, STRONG (N:alloc)
subtree_destroyer new_root(rtree::create_node<Allocators, internal_node>::apply(m_allocators), m_allocators); // MAY THROW, STRONG (N:alloc)
BOOST_TRY
{
@@ -365,7 +365,7 @@ protected:
}
BOOST_CATCH(...)
{
// clear new root to not delete in the ~node_auto_ptr() potentially stored old root node
// clear new root to not delete in the ~subtree_destroyer() potentially stored old root node
rtree::elements(rtree::get<internal_node>(*new_root)).clear();
BOOST_RETHROW // RETHROW
}

View File

@@ -0,0 +1,134 @@
// Boost.Geometry Index
//
// R-tree iterator visitor implementation
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
class iterator
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
{
public:
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename Allocators::size_type size_type;
typedef typename Allocators::const_reference const_reference;
typedef typename Allocators::node_pointer node_pointer;
typedef typename rtree::elements_type<internal_node>::type::const_iterator internal_iterator;
typedef typename rtree::elements_type<leaf>::type leaf_elements;
typedef typename rtree::elements_type<leaf>::type::const_iterator leaf_iterator;
inline iterator()
: m_values(NULL)
, m_current()
{}
inline void operator()(internal_node const& n)
{
typedef typename rtree::elements_type<internal_node>::type elements_type;
elements_type const& elements = rtree::elements(n);
m_internal_stack.push_back(std::make_pair(elements.begin(), elements.end()));
}
inline void operator()(leaf const& n)
{
m_values = ::boost::addressof(rtree::elements(n));
m_current = rtree::elements(n).begin();
}
const_reference dereference() const
{
BOOST_GEOMETRY_INDEX_ASSERT(m_values, "not dereferencable");
return *m_current;
}
void initialize(node_pointer root)
{
rtree::apply_visitor(*this, *root);
search_value();
}
void increment()
{
++m_current;
search_value();
}
void search_value()
{
for (;;)
{
// if leaf is choosen, move to the next value in leaf
if ( m_values )
{
// there are more values in the current leaf
if ( m_current != m_values->end() )
{
return;
}
// no more values, clear current leaf
else
{
m_values = 0;
}
}
// if leaf isn't choosen, move to the next leaf
else
{
// return if there is no more nodes to traverse
if ( m_internal_stack.empty() )
return;
// no more children in current node, remove it from stack
if ( m_internal_stack.back().first == m_internal_stack.back().second )
{
m_internal_stack.pop_back();
continue;
}
internal_iterator it = m_internal_stack.back().first;
++m_internal_stack.back().first;
// push the next node to the stack
rtree::apply_visitor(*this, *(it->second));
}
}
}
bool is_end() const
{
return 0 == m_values;
}
friend bool operator==(iterator const& l, iterator const& r)
{
return (l.m_values == r.m_values) && (0 == l.m_values || l.m_current == r.m_current );
}
private:
std::vector< std::pair<internal_iterator, internal_iterator> > m_internal_stack;
const leaf_elements * m_values;
leaf_iterator m_current;
};
}}} // namespace detail::rtree::visitors
}}} // namespace boost::geometry::index
#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP

View File

@@ -30,7 +30,7 @@ class remove
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::node_pointer node_pointer;
typedef typename Allocators::size_type size_type;
@@ -264,7 +264,7 @@ private:
// destroy current and remaining nodes
for ( ; it != m_underflowed_nodes.rend() ; ++it )
{
node_auto_ptr dummy(it->second, m_allocators);
subtree_destroyer dummy(it->second, m_allocators);
}
//m_underflowed_nodes.clear();

View File

@@ -94,10 +94,18 @@ public:
static const unsigned predicates_len = index::detail::predicates_length<Predicates>::value;
inline spatial_query_incremental()
: m_translator(NULL)
// , m_pred()
, m_values(NULL)
, m_current()
{}
inline spatial_query_incremental(Translator const& t, Predicates const& p)
: m_translator(::boost::addressof(t))
, m_pred(p)
, m_values(0)
, m_values(NULL)
, m_current()
{}
inline void operator()(internal_node const& n)

View File

@@ -1,6 +1,6 @@
// Boost.Geometry Index
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -353,7 +353,7 @@ class load
typedef typename Options::parameters_type parameters_type;
typedef typename Allocators::node_pointer node_pointer;
typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::size_type size_type;
public:
@@ -385,7 +385,7 @@ private:
if ( current_level < leafs_level )
{
node_pointer n = rtree::create_node<Allocators, internal_node>::apply(allocators); // MAY THROW (A)
node_auto_ptr auto_remover(n, allocators);
subtree_destroyer auto_remover(n, allocators);
internal_node & in = rtree::get<internal_node>(*n);
elements_type & elements = rtree::elements(in);
@@ -408,7 +408,7 @@ private:
BOOST_GEOMETRY_INDEX_ASSERT(current_level == leafs_level, "unexpected value");
node_pointer n = rtree::create_node<Allocators, leaf>::apply(allocators); // MAY THROW (A)
node_auto_ptr auto_remover(n, allocators);
subtree_destroyer auto_remover(n, allocators);
leaf & l = rtree::get<leaf>(*n);
typedef typename rtree::elements_type<leaf>::type elements_type;
@@ -537,7 +537,7 @@ void load(Archive & ar, boost::geometry::index::rtree<V, P, I, E, A> & rt, unsig
typedef typename options_type::parameters_type parameters_type;
typedef typename allocators_type::node_pointer node_pointer;
typedef detail::rtree::node_auto_ptr<value_type, options_type, translator_type, box_type, allocators_type> node_auto_ptr;
typedef detail::rtree::subtree_destroyer<value_type, options_type, translator_type, box_type, allocators_type> subtree_destroyer;
view tree(rt);
@@ -554,7 +554,7 @@ void load(Archive & ar, boost::geometry::index::rtree<V, P, I, E, A> & rt, unsig
n = detail::rtree::load<value_type, options_type, translator_type, box_type, allocators_type>
::apply(ar, version, leafs_level, loaded_values_count, params, tree.members().translator(), tree.members().allocators()); // MAY THROW
node_auto_ptr remover(n, tree.members().allocators());
subtree_destroyer remover(n, tree.members().allocators());
if ( loaded_values_count != values_count )
BOOST_THROW_EXCEPTION(std::runtime_error("unexpected number of values")); // TODO change exception type
remover.release();
@@ -564,7 +564,7 @@ void load(Archive & ar, boost::geometry::index::rtree<V, P, I, E, A> & rt, unsig
tree.members().values_count = values_count;
tree.members().leafs_level = leafs_level;
node_auto_ptr remover(tree.members().root, tree.members().allocators());
subtree_destroyer remover(tree.members().root, tree.members().allocators());
tree.members().root = n;
}

View File

@@ -70,8 +70,7 @@ inline size_t default_rstar_reinserted_elements_d_calc(size_t max_elements, size
\tparam MinElements Minimum number of elements in nodes. Default: 0.3*Max.
*/
template <size_t MaxElements,
size_t MinElements = detail::default_min_elements_s<MaxElements>::value
>
size_t MinElements = detail::default_min_elements_s<MaxElements>::value>
struct linear
{
BOOST_MPL_ASSERT_MSG((0 < MinElements && 2*MinElements <= MaxElements+1),

View File

@@ -2,7 +2,7 @@
//
// Spatial query predicates
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -43,10 +43,15 @@ bgi::query(spatial_index, bgi::contains(box), std::back_inserter(result));
\param g The Geometry object.
*/
template <typename Geometry> inline
detail::spatial_predicate<Geometry, detail::contains_tag, false>
detail::predicates::spatial_predicate<Geometry, detail::predicates::contains_tag, false>
contains(Geometry const& g)
{
return detail::spatial_predicate<Geometry, detail::contains_tag, false>(g);
return detail::predicates::spatial_predicate
<
Geometry,
detail::predicates::contains_tag,
false
>(g);
}
/*!
@@ -68,10 +73,15 @@ bgi::query(spatial_index, bgi::covered_by(box), std::back_inserter(result));
\param g The Geometry object.
*/
template <typename Geometry> inline
detail::spatial_predicate<Geometry, detail::covered_by_tag, false>
detail::predicates::spatial_predicate<Geometry, detail::predicates::covered_by_tag, false>
covered_by(Geometry const& g)
{
return detail::spatial_predicate<Geometry, detail::covered_by_tag, false>(g);
return detail::predicates::spatial_predicate
<
Geometry,
detail::predicates::covered_by_tag,
false
>(g);
}
/*!
@@ -93,10 +103,15 @@ bgi::query(spatial_index, bgi::covers(box), std::back_inserter(result));
\param g The Geometry object.
*/
template <typename Geometry> inline
detail::spatial_predicate<Geometry, detail::covers_tag, false>
detail::predicates::spatial_predicate<Geometry, detail::predicates::covers_tag, false>
covers(Geometry const& g)
{
return detail::spatial_predicate<Geometry, detail::covers_tag, false>(g);
return detail::predicates::spatial_predicate
<
Geometry,
detail::predicates::covers_tag,
false
>(g);
}
/*!
@@ -118,10 +133,15 @@ bgi::query(spatial_index, bgi::disjoint(box), std::back_inserter(result));
\param g The Geometry object.
*/
template <typename Geometry> inline
detail::spatial_predicate<Geometry, detail::disjoint_tag, false>
detail::predicates::spatial_predicate<Geometry, detail::predicates::disjoint_tag, false>
disjoint(Geometry const& g)
{
return detail::spatial_predicate<Geometry, detail::disjoint_tag, false>(g);
return detail::predicates::spatial_predicate
<
Geometry,
detail::predicates::disjoint_tag,
false
>(g);
}
/*!
@@ -145,10 +165,15 @@ bgi::query(spatial_index, bgi::intersects(polygon), std::back_inserter(result));
\param g The Geometry object.
*/
template <typename Geometry> inline
detail::spatial_predicate<Geometry, detail::intersects_tag, false>
detail::predicates::spatial_predicate<Geometry, detail::predicates::intersects_tag, false>
intersects(Geometry const& g)
{
return detail::spatial_predicate<Geometry, detail::intersects_tag, false>(g);
return detail::predicates::spatial_predicate
<
Geometry,
detail::predicates::intersects_tag,
false
>(g);
}
/*!
@@ -170,10 +195,15 @@ bgi::query(spatial_index, bgi::overlaps(box), std::back_inserter(result));
\param g The Geometry object.
*/
template <typename Geometry> inline
detail::spatial_predicate<Geometry, detail::overlaps_tag, false>
detail::predicates::spatial_predicate<Geometry, detail::predicates::overlaps_tag, false>
overlaps(Geometry const& g)
{
return detail::spatial_predicate<Geometry, detail::overlaps_tag, false>(g);
return detail::predicates::spatial_predicate
<
Geometry,
detail::predicates::overlaps_tag,
false
>(g);
}
#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
@@ -192,10 +222,15 @@ returns true.
\param g The Geometry object.
*/
template <typename Geometry> inline
detail::spatial_predicate<Geometry, detail::touches_tag, false>
detail::predicates::spatial_predicate<Geometry, detail::predicates::touches_tag, false>
touches(Geometry const& g)
{
return detail::spatial_predicate<Geometry, detail::touches_tag, false>(g);
return detail::predicates::spatial_predicate
<
Geometry,
detail::predicates::touches_tag,
false
>(g);
}
#endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
@@ -219,10 +254,15 @@ bgi::query(spatial_index, bgi::within(box), std::back_inserter(result));
\param g The Geometry object.
*/
template <typename Geometry> inline
detail::spatial_predicate<Geometry, detail::within_tag, false>
detail::predicates::spatial_predicate<Geometry, detail::predicates::within_tag, false>
within(Geometry const& g)
{
return detail::spatial_predicate<Geometry, detail::within_tag, false>(g);
return detail::predicates::spatial_predicate
<
Geometry,
detail::predicates::within_tag,
false
>(g);
}
/*!
@@ -259,10 +299,10 @@ std::back_inserter(result));
\param pred The unary predicate function or function object.
*/
template <typename UnaryPredicate> inline
detail::satisfies<UnaryPredicate, false>
detail::predicates::satisfies<UnaryPredicate, false>
satisfies(UnaryPredicate const& pred)
{
return detail::satisfies<UnaryPredicate, false>(pred);
return detail::predicates::satisfies<UnaryPredicate, false>(pred);
}
/*!
@@ -289,10 +329,10 @@ Only one \c nearest() predicate may be used in a query.
\param k The maximum number of values to return.
*/
template <typename Geometry> inline
detail::nearest<Geometry>
detail::predicates::nearest<Geometry>
nearest(Geometry const& geometry, unsigned k)
{
return detail::nearest<Geometry>(geometry, k);
return detail::predicates::nearest<Geometry>(geometry, k);
}
#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
@@ -319,15 +359,15 @@ Only one distance predicate (\c nearest() or \c path()) may be used in a query.
\param k The maximum number of values to return.
*/
template <typename SegmentOrLinestring> inline
detail::path<SegmentOrLinestring>
detail::predicates::path<SegmentOrLinestring>
path(SegmentOrLinestring const& linestring, unsigned k)
{
return detail::path<SegmentOrLinestring>(linestring, k);
return detail::predicates::path<SegmentOrLinestring>(linestring, k);
}
#endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
namespace detail {
namespace detail { namespace predicates {
// operator! generators
@@ -378,7 +418,7 @@ operator&&(boost::tuples::cons<Head, Tail> const& t, Pred const& p)
>::apply(t, p);
}
} // namespace detail
}} // namespace detail::predicates
}}} // namespace boost::geometry::index

View File

@@ -3,7 +3,7 @@
// R-tree implementation
//
// Copyright (c) 2008 Federico J. Fernandez.
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -59,6 +59,7 @@
#include <boost/geometry/index/detail/algorithms/is_valid.hpp>
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
#include <boost/geometry/index/detail/rtree/visitors/iterator.hpp>
#include <boost/geometry/index/detail/rtree/visitors/remove.hpp>
#include <boost/geometry/index/detail/rtree/visitors/copy.hpp>
#include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
@@ -78,6 +79,7 @@
#include <boost/geometry/index/detail/rtree/utilities/view.hpp>
#include <boost/geometry/index/detail/rtree/iterators.hpp>
#include <boost/geometry/index/detail/rtree/query_iterators.hpp>
#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
@@ -96,12 +98,13 @@ namespace boost { namespace geometry { namespace index {
/*!
\brief The R-tree spatial index.
This is self-balancing spatial index capable to store various types of Values and balancing algorithms.
This is self-balancing spatial index capable to store various types of Values
and balancing algorithms.
\par Parameters
The user must pass a type defining the Parameters which will
be used in rtree creation process. This type is used e.g. to specify balancing algorithm
with specific parameters like min and max number of elements in node.
be used in rtree creation process. This type is used e.g. to specify balancing
algorithm with specific parameters like min and max number of elements in node.
\par
Predefined algorithms with compile-time parameters are:
@@ -116,23 +119,31 @@ Predefined algorithms with run-time parameters are:
\li \c boost::geometry::index::dynamic_rstar.
\par IndexableGetter
The object of IndexableGetter type translates from Value to Indexable each time r-tree requires it. Which means that this
operation is done for each Value access. Therefore the IndexableGetter should return the Indexable by
const reference instead of a value. Default one can translate all types adapted to Point, Box or Segment
concepts (called Indexables). It also handles <tt>std::pair<Indexable, T></tt> and
<tt>boost::tuple<Indexable, ...></tt>. For example, if <tt>std::pair<Box, int></tt> is stored in the
container, the default IndexableGetter translates from <tt>std::pair<Box, int> const&</tt> to <tt>Box const&</tt>.
The object of IndexableGetter type translates from Value to Indexable each time
r-tree requires it. This means that this operation is done for each Value
access. Therefore the IndexableGetter should return the Indexable by
a reference type. The Indexable should not be calculated since it could harm
the performance. The default IndexableGetter can translate all types adapted
to Point, Box or Segment concepts (called Indexables). Furthermore, it can
handle <tt>std::pair<Indexable, T></tt>, <tt>boost::tuple<Indexable, ...></tt>
and <tt>std::tuple<Indexable, ...></tt> when possible. For example, for Value
of type <tt>std::pair<Box, int></tt>, the default IndexableGetter translates
from <tt>std::pair<Box, int> const&</tt> to <tt>Box const&</tt>.
\par EqualTo
The object of EqualTo type compares Values and returns <tt>true</tt> if they're equal. It's similar to <tt>std::equal_to<></tt>.
The default EqualTo returns the result of <tt>boost::geometry::equals()</tt> for types adapted to some Geometry concept
defined in Boost.Geometry and the result of operator= for other types. Components of Pairs and Tuples are compared left-to-right.
The object of EqualTo type compares Values and returns <tt>true</tt> if they
are equal. It's similar to <tt>std::equal_to<></tt>. The default EqualTo
returns the result of <tt>boost::geometry::equals()</tt> for types adapted to
some Geometry concept defined in Boost.Geometry and the result of
<tt>operator==</tt> for other types. Components of Pairs and Tuples are
compared left-to-right.
\tparam Value The type of objects stored in the container.
\tparam Parameters Compile-time parameters.
\tparam IndexableGetter The function object extracting Indexable from Value.
\tparam EqualTo The function object comparing objects of type Value.
\tparam Allocator The allocator used to allocate/deallocate memory, construct/destroy nodes and Values.
\tparam Allocator The allocator used to allocate/deallocate memory,
construct/destroy nodes and Values.
*/
template <
typename Value,
@@ -188,7 +199,7 @@ private:
typedef typename allocators_type::node_pointer node_pointer;
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef detail::rtree::node_auto_ptr<value_type, options_type, translator_type, box_type, allocators_type> node_auto_ptr;
typedef detail::rtree::subtree_destroyer<value_type, options_type, translator_type, box_type, allocators_type> subtree_destroyer;
friend class detail::rtree::utilities::view<rtree>;
#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
@@ -211,8 +222,17 @@ public:
/*! \brief Unsigned integral type used by the container. */
typedef typename allocators_type::size_type size_type;
/*! \brief Type of const query iterator. */
typedef index::detail::rtree::iterators::query_iterator<value_type, allocators_type> const_query_iterator;
/*! \brief Type of const iterator, category ForwardIterator. */
typedef index::detail::rtree::iterators::iterator
<
value_type, options_type, translator_type, box_type, allocators_type
> const_iterator;
/*! \brief Type of const query iterator, category ForwardIterator. */
typedef index::detail::rtree::iterators::query_iterator
<
value_type, allocators_type
> const_query_iterator;
public:
@@ -757,6 +777,27 @@ public:
tree.query(bgi::overlaps(box) && bgi::satisfies(my_fun), std::back_inserter(result));
// return 5 elements nearest to pt and elements are intersecting box
tree.query(bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result));
// For each found value do_something (it is a type of function object)
tree.query(bgi::intersects(box),
boost::make_function_output_iterator(do_something()));
// For each value stored in the rtree do_something
// always_true is a type of function object always returning true
tree.query(bgi::satisfies(always_true()),
boost::make_function_output_iterator(do_something()));
// C++11 (lambda expression)
tree.query(bgi::intersects(box),
boost::make_function_output_iterator([](value_type const& val){
// do something
}));
// C++14 (generic lambda expression)
tree.query(bgi::intersects(box),
boost::make_function_output_iterator([](auto const& val){
// do something
}));
\endverbatim
\par Throws
@@ -765,7 +806,7 @@ public:
\warning
Only one \c nearest() perdicate may be passed to the query. Passing more of them results in compile-time error.
\param predicates Predicates.
\param out_it The output iterator, e.g. generated by std::back_inserter().
@@ -785,11 +826,11 @@ public:
}
/*!
\brief Returns the query iterator pointing at the begin of the query range.
\brief Returns a query iterator pointing at the begin of the query range.
This method returns an iterator which may be used to perform iterative queries.
For the information about predicates which may be passed to this method see query().
This method returns the iterator which may be used to perform iterative queries. For the information
about the predicates which may be passed to this method see query().
\par Example
\verbatim
for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
@@ -799,12 +840,29 @@ public:
if ( has_enough_nearest_values() )
break;
}
// C++11 (auto)
for ( auto it = tree.qbegin(bgi::nearest(pt, 3)) ; it != tree.qend() ; ++it )
{
// do something with value
}
// C++14 (generic lambda expression)
std::for_each(tree.qbegin(bgi::nearest(pt, 3)), tree.qend(), [](auto const& val){
// do something with value
});
\endverbatim
\par Iterator category
ForwardIterator
\par Throws
If predicates copy throws.
If allocation throws.
\warning
The modification of the rtree may invalidate the iterators.
\param predicates Predicates.
\return The iterator pointing at the begin of the query range.
@@ -816,10 +874,10 @@ public:
}
/*!
\brief Returns the query iterator pointing at the end of the query range.
\brief Returns a query iterator pointing at the end of the query range.
This method returns an iterator which may be used to check if the query has ended.
This method returns the iterator which may be used to check if the query has ended.
\par Example
\verbatim
for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
@@ -829,10 +887,27 @@ public:
if ( has_enough_nearest_values() )
break;
}
// C++11 (auto)
for ( auto it = tree.qbegin(bgi::nearest(pt, 3)) ; it != tree.qend() ; ++it )
{
// do something with value
}
// C++14 (generic lambda expression)
std::for_each(tree.qbegin(bgi::nearest(pt, 3)), tree.qend(), [](auto const& val){
// do something with value
});
\endverbatim
\par Iterator category
ForwardIterator
\par Throws
Nothing
\warning
The modification of the rtree may invalidate the iterators.
\return The iterator pointing at the end of the query range.
*/
@@ -845,10 +920,10 @@ public:
private:
#endif
/*!
\brief Returns the query iterator pointing at the begin of the query range.
\brief Returns a query iterator pointing at the begin of the query range.
This method returns the iterator which may be used to perform iterative queries. For the information
about the predicates which may be passed to this method see query().
This method returns an iterator which may be used to perform iterative queries.
For the information about predicates which may be passed to this method see query().
The type of the returned iterator depends on the type of passed Predicates but the iterator of this type
may be assigned to the variable of const_query_iterator type. If you'd like to use the type of the iterator
@@ -858,16 +933,24 @@ private:
\par Example
\verbatim
// Store the result in the container using std::copy() - it requires both iterators of the same type
std::copy(tree.qbegin(bgi::intersects(box)), tree.qend(bgi::intersects(box)), std::back_inserter(result));
std::copy(tree.qbegin_(bgi::intersects(box)), tree.qend_(bgi::intersects(box)), std::back_inserter(result));
// Store the result in the container using std::copy() and type-erased iterators
Rtree::const_query_iterator first = tree.qbegin(bgi::intersects(box));
Rtree::const_query_iterator last = tree.qend();
Rtree::const_query_iterator first = tree.qbegin_(bgi::intersects(box));
Rtree::const_query_iterator last = tree.qend_();
std::copy(first, last, std::back_inserter(result));
// Boost.Typeof
typedef BOOST_TYPEOF(tree.qbegin(bgi::nearest(pt, 10000))) Iter;
for ( Iter it = tree.qbegin(bgi::nearest(pt, 10000)) ; it != tree.qend() ; ++it )
for ( Iter it = tree.qbegin_(bgi::nearest(pt, 10000)) ; it != tree.qend_() ; ++it )
{
// do something with value
if ( has_enough_nearest_values() )
break;
}
// C++11 (auto)
for ( auto it = tree.qbegin_(bgi::nearest(pt, 10000)) ; it != tree.qend_() ; ++it )
{
// do something with value
if ( has_enough_nearest_values() )
@@ -875,10 +958,16 @@ private:
}
\endverbatim
\par Iterator category
ForwardIterator
\par Throws
If predicates copy throws.
If allocation throws.
\warning
The modification of the rtree may invalidate the iterators.
\param predicates Predicates.
\return The iterator pointing at the begin of the query range.
@@ -928,12 +1017,18 @@ private:
\par Example
\verbatim
// Store the result in the container using std::copy() - it requires both iterators of the same type
std::copy(tree.qbegin(bgi::intersects(box)), tree.qend(bgi::intersects(box)), std::back_inserter(result));
std::copy(tree.qbegin_(bgi::intersects(box)), tree.qend_(bgi::intersects(box)), std::back_inserter(result));
\endverbatim
\par Iterator category
ForwardIterator
\par Throws
If predicates copy throws.
\warning
The modification of the rtree may invalidate the iterators.
\param predicates Predicates.
\return The iterator pointing at the end of the query range.
@@ -980,13 +1075,21 @@ private:
\par Example
\verbatim
// Store the result in the container using std::copy() and type-erased iterators
Rtree::const_query_iterator first = tree.qbegin(bgi::intersects(box));
Rtree::const_query_iterator last = tree.qend();
Rtree::const_query_iterator first = tree.qbegin_(bgi::intersects(box));
Rtree::const_query_iterator last = tree.qend_();
std::copy(first, last, std::back_inserter(result));
// Boost.Typeof
typedef BOOST_TYPEOF(tree.qbegin(bgi::nearest(pt, 10000))) Iter;
for ( Iter it = tree.qbegin(bgi::nearest(pt, 10000)) ; it != tree.qend() ; ++it )
for ( Iter it = tree.qbegin_(bgi::nearest(pt, 10000)) ; it != tree.qend_() ; ++it )
{
// do something with value
if ( has_enough_nearest_values() )
break;
}
// C++11 (auto)
for ( auto it = tree.qbegin_(bgi::nearest(pt, 10000)) ; it != tree.qend_() ; ++it )
{
// do something with value
if ( has_enough_nearest_values() )
@@ -994,8 +1097,14 @@ private:
}
\endverbatim
\par Iterator category
ForwardIterator
\par Throws
Nothing
\warning
The modification of the rtree may invalidate the iterators.
\return The iterator pointing at the end of the query range.
*/
@@ -1007,6 +1116,88 @@ private:
public:
/*!
\brief Returns the iterator pointing at the begin of the rtree values range.
This method returns the iterator which may be used to iterate over all values
stored in the rtree.
\par Example
\verbatim
// Copy all values into the vector
std::copy(tree.begin(), tree.end(), std::back_inserter(vec));
for ( Rtree::const_iterator it = tree.begin() ; it != tree.end() ; ++it )
{
// do something with value
}
// C++11 (auto)
for ( auto it = tree.begin() ; it != tree.end() ; ++it )
{
// do something with value
}
// C++14 (generic lambda expression)
std::for_each(tree.begin(), tree.end(), [](auto const& val){
// do something with value
})
\endverbatim
\par Iterator category
ForwardIterator
\par Throws
If allocation throws.
\warning
The modification of the rtree may invalidate the iterators.
\return The iterator pointing at the begin of the range.
*/
const_iterator begin() const
{
if ( !m_members.root )
return const_iterator();
return const_iterator(m_members.root);
}
/*!
\brief Returns the iterator pointing at the end of the rtree values range.
This method returns the iterator which may be compared with the iterator returned by begin()
in order to check if the iteration has ended.
\par Example
\verbatim
for ( Rtree::const_iterator it = tree.begin() ; it != tree.end() ; ++it )
{
// do something with value
}
// C++11 (lambda expression)
std::for_each(tree.begin(), tree.end(), [](value_type const& val){
// do something with value
})
\endverbatim
\par Iterator category
ForwardIterator
\par Throws
Nothing.
\warning
The modification of the rtree may invalidate the iterators.
\return The iterator pointing at the end of the range.
*/
const_iterator end() const
{
return const_iterator();
}
/*!
\brief Returns the number of stored values.
@@ -1088,6 +1279,8 @@ public:
template <typename ValueOrIndexable>
size_type count(ValueOrIndexable const& vori) const
{
// the input should be convertible to Value or Indexable type
enum { as_val = 0, as_ind, dont_know };
typedef boost::mpl::int_
<
@@ -1113,15 +1306,9 @@ public:
indexable_type
>::type value_or_indexable;
if ( !m_members.root )
return 0;
detail::rtree::visitors::count<value_or_indexable, value_type, options_type, translator_type, box_type, allocators_type>
count_v(vori, m_members.translator());
detail::rtree::apply_visitor(count_v, *m_members.root);
return count_v.found_count;
// NOTE: If an object of convertible but not the same type is passed
// into the function, here a temporary will be created.
return this->template raw_count<value_or_indexable>(vori);
}
/*!
@@ -1357,7 +1544,7 @@ private:
dst.m_members.parameters() = src.m_members.parameters();
}
// TODO use node_auto_ptr
// TODO use subtree_destroyer
if ( dst.m_members.root )
{
detail::rtree::visitors::destroy<value_type, options_type, translator_type, box_type, allocators_type>
@@ -1493,6 +1680,33 @@ private:
return distance_v.finish();
}
/*!
\brief Count elements corresponding to value or indexable.
\par Exception-safety
strong
*/
template <typename ValueOrIndexable>
size_type raw_count(ValueOrIndexable const& vori) const
{
if ( !m_members.root )
return 0;
detail::rtree::visitors::count
<
ValueOrIndexable,
value_type,
options_type,
translator_type,
box_type,
allocators_type
> count_v(vori, m_members.translator());
detail::rtree::apply_visitor(count_v, *m_members.root);
return count_v.found_count;
}
struct members_holder
: public translator_type
@@ -1731,6 +1945,10 @@ bgi::query(tree, bgi::intersects(poly) && !bgi::within(box), std::back_inserter(
bgi::query(tree, bgi::overlaps(box) && bgi::satisfies(my_fun), std::back_inserter(result));
// return 5 elements nearest to pt and elements are intersecting box
bgi::query(tree, bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result));
// For each found value do_something (it is a type of function object)
tree.query(bgi::intersects(box),
boost::make_function_output_iterator(do_something()));
\endverbatim
\par Throws
@@ -1765,20 +1983,19 @@ about the predicates which may be passed to this method see query().
\par Example
\verbatim
for ( Rtree::const_query_iterator it = qbegin(tree, bgi::nearest(pt, 10000)) ;
it != qend(tree) ; ++it )
{
// do something with value
if ( has_enough_nearest_values() )
break;
}
std::for_each(bgi::qbegin(tree, bgi::nearest(pt, 3)), bgi::qend(tree), do_something());
\endverbatim
\par Iterator category
ForwardIterator
\par Throws
If predicates copy throws.
If allocation throws.
\warning
The modification of the rtree may invalidate the iterators.
\ingroup rtree_functions
\param tree The rtree.
@@ -1802,19 +2019,18 @@ This method returns the iterator which may be used to check if the query has end
\par Example
\verbatim
for ( Rtree::const_query_iterator it = qbegin(tree, bgi::nearest(pt, 10000)) ;
it != qend(tree) ; ++it )
{
// do something with value
if ( has_enough_nearest_values() )
break;
}
std::for_each(bgi::qbegin(tree, bgi::nearest(pt, 3)), bgi::qend(tree), do_something());
\endverbatim
\par Iterator category
ForwardIterator
\par Throws
Nothing
\warning
The modification of the rtree may invalidate the iterators.
\ingroup rtree_functions
\return The iterator pointing at the end of the query range.
@@ -1826,6 +2042,72 @@ qend(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
return tree.qend();
}
/*!
\brief Returns the iterator pointing at the begin of the rtree values range.
This method returns the iterator which may be used to iterate over all values
stored in the rtree.
\par Example
\verbatim
std::for_each(bgi::begin(tree), bgi::end(tree), do_something());
// the same as
std::for_each(boost::begin(tree), boost::end(tree), do_something());
\endverbatim
\par Iterator category
ForwardIterator
\par Throws
If allocation throws.
\warning
The modification of the rtree may invalidate the iterators.
\ingroup rtree_functions
\return The iterator pointing at the begin of the range.
*/
template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator> inline
typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_iterator
begin(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
{
return tree.begin();
}
/*!
\brief Returns the iterator pointing at the end of the rtree values range.
This method returns the iterator which may be compared with the iterator returned by begin()
in order to check if the iteration has ended.
\par Example
\verbatim
std::for_each(bgi::begin(tree), bgi::end(tree), do_something());
// the same as
std::for_each(boost::begin(tree), boost::end(tree), do_something());
\endverbatim
\par Iterator category
ForwardIterator
\par Throws
Nothing.
\warning
The modification of the rtree may invalidate the iterators.
\ingroup rtree_functions
\return The iterator pointing at the end of the range.
*/
template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator> inline
typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_iterator
end(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
{
return tree.end();
}
/*!
\brief Remove all values from the index.
@@ -1912,6 +2194,23 @@ inline void swap(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> &
}}} // namespace boost::geometry::index
// Boost.Range adaptation
namespace boost {
template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
struct range_mutable_iterator
<
boost::geometry::index::rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>
>
{
typedef typename boost::geometry::index::rtree
<
Value, Parameters, IndexableGetter, EqualTo, Allocator
>::const_iterator type;
};
} // namespace boost
// TODO: don't include the implementation at the end of the file
#include <boost/geometry/algorithms/detail/comparable_distance/implementation.hpp>

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -37,9 +37,6 @@
#include <boost/geometry/strategies/transform/map_transformer.hpp>
#include <boost/geometry/views/segment_view.hpp>
#include <boost/geometry/multi/algorithms/envelope.hpp>
#include <boost/geometry/multi/algorithms/num_points.hpp>
#include <boost/geometry/io/svg/write_svg.hpp>
// Helper geometries (all points are transformed to integer-points)

View File

@@ -215,12 +215,9 @@ private:
--m_outer_it;
}
while ( empty(m_outer_it) );
m_inner_it = --AccessInnerEnd::apply(*m_outer_it);
}
else
{
--m_inner_it;
}
m_inner_it = AccessInnerEnd::apply(*m_outer_it);
}
--m_inner_it;
}
};

View File

@@ -1,11 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2013.
// Modifications copyright (c) 2013, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2015.
// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -17,65 +17,8 @@
#ifndef BOOST_GEOMETRY_MULTI_HPP
#define BOOST_GEOMETRY_MULTI_HPP
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/geometry_id.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/is_areal.hpp>
#include <boost/geometry/core/point_order.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/topological_dimension.hpp>
#include <boost/geometry/algorithms/append.hpp>
#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/centroid.hpp>
#include <boost/geometry/algorithms/clear.hpp>
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/algorithms/correct.hpp>
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/disjoint.hpp>
#include <boost/geometry/algorithms/distance.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/equals.hpp>
#include <boost/geometry/algorithms/for_each.hpp>
#include <boost/geometry/algorithms/intersection.hpp>
#include <boost/geometry/algorithms/length.hpp>
#include <boost/geometry/algorithms/num_geometries.hpp>
#include <boost/geometry/algorithms/num_interior_rings.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/algorithms/perimeter.hpp>
#include <boost/geometry/algorithms/remove_spikes.hpp>
#include <boost/geometry/algorithms/reverse.hpp>
#include <boost/geometry/algorithms/simplify.hpp>
#include <boost/geometry/algorithms/transform.hpp>
#include <boost/geometry/algorithms/unique.hpp>
#include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
#include <boost/geometry/algorithms/detail/for_each_range.hpp>
#include <boost/geometry/algorithms/detail/multi_modify_with_predicate.hpp>
#include <boost/geometry/algorithms/detail/multi_sum.hpp>
#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
#include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/views/detail/range_type.hpp>
#include <boost/geometry/strategies/cartesian/centroid_average.hpp>
#include <boost/geometry/io/dsv/write.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
// keep this file for now, for backward compatibility
// functionality-wise, make it equivalent to boost/geometry/geometry.hpp
#include <boost/geometry/geometry.hpp>
#endif // BOOST_GEOMETRY_MULTI_HPP

View File

@@ -242,7 +242,7 @@ struct segments_direction
static inline return_type segments_collinear(
Segment1 const& , Segment2 const& , bool opposite,
int a1_wrt_b, int a2_wrt_b, int b1_wrt_a, int b2_wrt_a,
Ratio const& ra_from_wrt_b, Ratio const& ra_to_wrt_b,
Ratio const& /*ra_from_wrt_b*/, Ratio const& /*ra_to_wrt_b*/,
Ratio const& /*rb_from_wrt_a*/, Ratio const& /*rb_to_wrt_a*/)
{
return_type r('c', opposite);

View File

@@ -19,6 +19,7 @@
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/strategies/side_info.hpp>
#include <boost/geometry/util/promote_integral.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
#include <boost/geometry/util/math.hpp>
@@ -60,12 +61,24 @@ struct segments_intersection_points
// denominator. In case of integer this results in an integer
// division.
BOOST_ASSERT(ratio.denominator() != 0);
set<0>(point, boost::numeric_cast<coordinate_type>(
get<0, 0>(segment)
+ ratio.numerator() * dx / ratio.denominator()));
set<1>(point, boost::numeric_cast<coordinate_type>(
get<0, 1>(segment)
+ ratio.numerator() * dy / ratio.denominator()));
typedef typename promote_integral<coordinate_type>::type promoted_type;
promoted_type const numerator
= boost::numeric_cast<promoted_type>(ratio.numerator());
promoted_type const denominator
= boost::numeric_cast<promoted_type>(ratio.denominator());
promoted_type const dx_promoted = boost::numeric_cast<promoted_type>(dx);
promoted_type const dy_promoted = boost::numeric_cast<promoted_type>(dy);
set<0>(point, get<0, 0>(segment) + boost::numeric_cast
<
coordinate_type
>(numerator * dx_promoted / denominator));
set<1>(point, get<0, 1>(segment) + boost::numeric_cast
<
coordinate_type
>(numerator * dy_promoted / denominator));
}

View File

@@ -200,7 +200,11 @@ struct relate_cartesian_segments
get<1>(robust_b1) - get<1>(robust_a1),
robust_db0, robust_db);
if (robust_da0 == 0)
math::detail::equals_factor_policy<robust_coordinate_type>
policy(robust_dx_a, robust_dy_a, robust_dx_b, robust_dy_b);
robust_coordinate_type const zero = 0;
if (math::detail::equals_by_policy(robust_da0, zero, policy)
|| math::detail::equals_by_policy(robust_db0, zero, policy))
{
// If this is the case, no rescaling is done for FP precision.
// We set it to collinear, but it indicates a robustness issue.

View File

@@ -46,6 +46,24 @@ namespace strategy { namespace side
template <typename CalculationType = void>
class side_by_triangle
{
template <typename Policy>
struct eps_policy
{
eps_policy() {}
template <typename Type>
eps_policy(Type const& a, Type const& b, Type const& c, Type const& d)
: policy(a, b, c, d)
{}
Policy policy;
};
struct eps_empty
{
eps_empty() {}
template <typename Type>
eps_empty(Type const&, Type const&, Type const&, Type const&) {}
};
public :
// Template member function, because it is not always trivial
@@ -61,10 +79,11 @@ public :
typename PromotedType,
typename P1,
typename P2,
typename P
typename P,
typename EpsPolicy
>
static inline
PromotedType side_value(P1 const& p1, P2 const& p2, P const& p)
PromotedType side_value(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & eps_policy)
{
CoordinateType const x = get<0>(p);
CoordinateType const y = get<1>(p);
@@ -79,6 +98,8 @@ public :
PromotedType const dpx = x - sx1;
PromotedType const dpy = y - sy1;
eps_policy = EpsPolicy(dx, dy, dpx, dpy);
return geometry::detail::determinant<PromotedType>
(
dx, dy,
@@ -87,6 +108,21 @@ public :
}
template
<
typename CoordinateType,
typename PromotedType,
typename P1,
typename P2,
typename P
>
static inline
PromotedType side_value(P1 const& p1, P2 const& p2, P const& p)
{
eps_empty dummy;
return side_value<CoordinateType, PromotedType>(p1, p2, p, dummy);
}
template
<
@@ -96,18 +132,18 @@ public :
>
struct compute_side_value
{
template <typename P1, typename P2, typename P>
static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p)
template <typename P1, typename P2, typename P, typename EpsPolicy>
static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp)
{
return side_value<CoordinateType, PromotedType>(p1, p2, p);
return side_value<CoordinateType, PromotedType>(p1, p2, p, epsp);
}
};
template <typename CoordinateType, typename PromotedType>
struct compute_side_value<CoordinateType, PromotedType, false>
{
template <typename P1, typename P2, typename P>
static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p)
template <typename P1, typename P2, typename P, typename EpsPolicy>
static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp)
{
// For robustness purposes, first check if any two points are
// the same; in this case simply return that the points are
@@ -135,24 +171,24 @@ public :
if (less(p, p2))
{
// p is the lexicographically smallest
return side_value<CoordinateType, PromotedType>(p, p1, p2);
return side_value<CoordinateType, PromotedType>(p, p1, p2, epsp);
}
else
{
// p2 is the lexicographically smallest
return side_value<CoordinateType, PromotedType>(p2, p, p1);
return side_value<CoordinateType, PromotedType>(p2, p, p1, epsp);
}
}
if (less(p1, p2))
{
// p1 is the lexicographically smallest
return side_value<CoordinateType, PromotedType>(p1, p2, p);
return side_value<CoordinateType, PromotedType>(p1, p2, p, epsp);
}
else
{
// p2 is the lexicographically smallest
return side_value<CoordinateType, PromotedType>(p2, p, p1);
return side_value<CoordinateType, PromotedType>(p2, p, p1, epsp);
}
}
};
@@ -191,13 +227,14 @@ public :
&& boost::is_integral<coordinate_type2>::value
&& boost::is_integral<coordinate_type3>::value;
eps_policy< math::detail::equals_factor_policy<promoted_type> > epsp;
promoted_type s = compute_side_value
<
coordinate_type, promoted_type, are_all_integral_coordinates
>::apply(p1, p2, p);
>::apply(p1, p2, p, epsp);
promoted_type const zero = promoted_type();
return math::equals(s, zero) ? 0
return math::detail::equals_by_policy(s, zero, epsp.policy) ? 0
: s > zero ? 1
: -1;
}

View File

@@ -23,6 +23,8 @@
#include <cmath>
#include <limits>
#include <boost/core/ignore_unused.hpp>
#include <boost/math/constants/constants.hpp>
#ifdef BOOST_GEOMETRY_SQRT_CHECK_FINITENESS
#include <boost/math/special_functions/fpclassify.hpp>
@@ -30,6 +32,7 @@
#include <boost/math/special_functions/round.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
@@ -43,11 +46,104 @@ namespace math
namespace detail
{
template <typename T>
inline T const& greatest(T const& v1, T const& v2)
{
return (std::max)(v1, v2);
}
template <typename Type, bool IsFloatingPoint>
template <typename T>
inline T const& greatest(T const& v1, T const& v2, T const& v3)
{
return (std::max)(greatest(v1, v2), v3);
}
template <typename T>
inline T const& greatest(T const& v1, T const& v2, T const& v3, T const& v4)
{
return (std::max)(greatest(v1, v2, v3), v4);
}
template <typename T>
inline T const& greatest(T const& v1, T const& v2, T const& v3, T const& v4, T const& v5)
{
return (std::max)(greatest(v1, v2, v3, v4), v5);
}
template <typename T,
bool IsFloatingPoint = boost::is_floating_point<T>::value>
struct abs
{
static inline T apply(T const& value)
{
T const zero = T();
return value < zero ? -value : value;
}
};
template <typename T>
struct abs<T, true>
{
static inline T apply(T const& value)
{
return fabs(value);
}
};
struct equals_default_policy
{
template <typename T>
static inline T apply(T const& a, T const& b)
{
// See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17
return greatest(abs<T>::apply(a), abs<T>::apply(b), T(1));
}
};
template <typename T,
bool IsFloatingPoint = boost::is_floating_point<T>::value>
struct equals_factor_policy
{
equals_factor_policy()
: factor(1) {}
explicit equals_factor_policy(T const& v)
: factor(greatest(abs<T>::apply(v), T(1)))
{}
equals_factor_policy(T const& v0, T const& v1, T const& v2, T const& v3)
: factor(greatest(abs<T>::apply(v0), abs<T>::apply(v1),
abs<T>::apply(v2), abs<T>::apply(v3),
T(1)))
{}
T const& apply(T const&, T const&) const
{
return factor;
}
T factor;
};
template <typename T>
struct equals_factor_policy<T, false>
{
equals_factor_policy() {}
explicit equals_factor_policy(T const&) {}
equals_factor_policy(T const& , T const& , T const& , T const& ) {}
static inline T apply(T const&, T const&)
{
return T(1);
}
};
template <typename Type,
bool IsFloatingPoint = boost::is_floating_point<Type>::value>
struct equals
{
static inline bool apply(Type const& a, Type const& b)
template <typename Policy>
static inline bool apply(Type const& a, Type const& b, Policy const&)
{
return a == b;
}
@@ -56,25 +152,31 @@ struct equals
template <typename Type>
struct equals<Type, true>
{
static inline Type get_max(Type const& a, Type const& b, Type const& c)
template <typename Policy>
static inline bool apply(Type const& a, Type const& b, Policy const& policy)
{
return (std::max)((std::max)(a, b), c);
}
boost::ignore_unused(policy);
static inline bool apply(Type const& a, Type const& b)
{
if (a == b)
{
return true;
}
// See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17,
// FUTURE: replace by some boost tool or boost::test::close_at_tolerance
return std::abs(a - b) <= std::numeric_limits<Type>::epsilon() * get_max(std::abs(a), std::abs(b), 1.0);
return abs<Type>::apply(a - b) <= std::numeric_limits<Type>::epsilon() * policy.apply(a, b);
}
};
template <typename Type, bool IsFloatingPoint>
template <typename T1, typename T2, typename Policy>
inline bool equals_by_policy(T1 const& a, T2 const& b, Policy const& policy)
{
return detail::equals
<
typename select_most_precise<T1, T2>::type
>::apply(a, b, policy);
}
template <typename Type,
bool IsFloatingPoint = boost::is_floating_point<Type>::value>
struct smaller
{
static inline bool apply(Type const& a, Type const& b)
@@ -88,7 +190,7 @@ struct smaller<Type, true>
{
static inline bool apply(Type const& a, Type const& b)
{
if (equals<Type, true>::apply(a, b))
if (equals<Type, true>::apply(a, b, equals_default_policy()))
{
return false;
}
@@ -97,8 +199,11 @@ struct smaller<Type, true>
};
template <typename Type, bool IsFloatingPoint>
struct equals_with_epsilon : public equals<Type, IsFloatingPoint> {};
template <typename Type,
bool IsFloatingPoint = boost::is_floating_point<Type>::value>
struct equals_with_epsilon
: public equals<Type, IsFloatingPoint>
{};
template
<
@@ -191,6 +296,63 @@ struct square_root<T, true>
};
template
<
typename T,
bool IsFundemantal = boost::is_fundamental<T>::value /* false */
>
struct modulo
{
typedef T return_type;
static inline T apply(T const& value1, T const& value2)
{
// for non-fundamental number types assume that a free
// function mod() is defined either:
// 1) at T's scope, or
// 2) at global scope
return mod(value1, value2);
}
};
template
<
typename Fundamental,
bool IsIntegral = boost::is_integral<Fundamental>::value
>
struct modulo_for_fundamental
{
typedef Fundamental return_type;
static inline Fundamental apply(Fundamental const& value1,
Fundamental const& value2)
{
return value1 % value2;
}
};
// specialization for floating-point numbers
template <typename Fundamental>
struct modulo_for_fundamental<Fundamental, false>
{
typedef Fundamental return_type;
static inline Fundamental apply(Fundamental const& value1,
Fundamental const& value2)
{
return std::fmod(value1, value2);
}
};
// specialization for fundamental number type
template <typename Fundamental>
struct modulo<Fundamental, true>
: modulo_for_fundamental<Fundamental>
{};
/*!
\brief Short construct to enable partial specialization for PI, currently not possible in Math.
*/
@@ -270,44 +432,36 @@ inline T relaxed_epsilon(T const& factor)
template <typename T1, typename T2>
inline bool equals(T1 const& a, T2 const& b)
{
typedef typename select_most_precise<T1, T2>::type select_type;
return detail::equals
<
select_type,
boost::is_floating_point<select_type>::type::value
>::apply(a, b);
typename select_most_precise<T1, T2>::type
>::apply(a, b, detail::equals_default_policy());
}
template <typename T1, typename T2>
inline bool equals_with_epsilon(T1 const& a, T2 const& b)
{
typedef typename select_most_precise<T1, T2>::type select_type;
return detail::equals_with_epsilon
<
select_type,
boost::is_floating_point<select_type>::type::value
>::apply(a, b);
typename select_most_precise<T1, T2>::type
>::apply(a, b, detail::equals_default_policy());
}
template <typename T1, typename T2>
inline bool smaller(T1 const& a, T2 const& b)
{
typedef typename select_most_precise<T1, T2>::type select_type;
return detail::smaller
<
select_type,
boost::is_floating_point<select_type>::type::value
typename select_most_precise<T1, T2>::type
>::apply(a, b);
}
template <typename T1, typename T2>
inline bool larger(T1 const& a, T2 const& b)
{
typedef typename select_most_precise<T1, T2>::type select_type;
return detail::smaller
<
select_type,
boost::is_floating_point<select_type>::type::value
typename select_most_precise<T1, T2>::type
>::apply(b, a);
}
@@ -358,6 +512,24 @@ sqrt(T const& value)
>::apply(value);
}
/*!
\brief Short utility to return the modulo of two values
\ingroup utility
\param value1 First value
\param value2 Second value
\return The result of the modulo operation on the (ordered) pair
(value1, value2)
*/
template <typename T>
inline typename detail::modulo<T>::return_type
mod(T const& value1, T const& value2)
{
return detail::modulo
<
T, boost::is_fundamental<T>::value
>::apply(value1, value2);
}
/*!
\brief Short utility to workaround gcc/clang problem that abs is converting to integer
and that older versions of MSVC does not support abs of long long...
@@ -366,8 +538,7 @@ sqrt(T const& value)
template<typename T>
inline T abs(T const& value)
{
T const zero = T();
return value < zero ? -value : value;
return detail::abs<T>::apply(value);
}
/*!
@@ -386,12 +557,11 @@ static inline int sign(T const& value)
\ingroup utility
\note If the source T is NOT an integral type and Result is an integral type
the value is rounded towards the closest integral value. Otherwise it's
just casted.
casted.
*/
template <typename Result, typename T>
inline Result round(T const& v)
{
// NOTE: boost::round() could be used instead but it throws in some situations
return detail::round<Result, T>::apply(v);
}

View File

@@ -0,0 +1,318 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_UTIL_PROMOTE_INTEGRAL_HPP
#define BOOST_GEOMETRY_UTIL_PROMOTE_INTEGRAL_HPP
// For now deactivate the use of multiprecision integers
// TODO: activate it later
#define BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER
#include <climits>
#include <cstddef>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/list.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/size_t.hpp>
#if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
#include <boost/multiprecision/cpp_int.hpp>
#endif
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_unsigned.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace promote_integral
{
// meta-function that returns the bit size of a type
template
<
typename T,
bool IsFundamental = boost::is_fundamental<T>::type::value
>
struct bit_size
{};
// for fundamental types, just return CHAR_BIT * sizeof(T)
template <typename T>
struct bit_size<T, true>
: boost::mpl::size_t<(CHAR_BIT * sizeof(T))>
{};
#if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
// partial specialization for cpp_int
template
<
unsigned MinSize,
unsigned MaxSize,
boost::multiprecision::cpp_integer_type SignType,
boost::multiprecision::cpp_int_check_type Checked,
typename Allocator,
boost::multiprecision::expression_template_option ExpressionTemplates
>
struct bit_size
<
boost::multiprecision::number
<
boost::multiprecision::cpp_int_backend
<
MinSize, MaxSize, SignType, Checked, Allocator
>,
ExpressionTemplates
>,
false
> : boost::mpl::size_t<MaxSize>
{};
#endif // BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER
template
<
typename T,
typename Iterator,
typename EndIterator,
std::size_t MinSize
>
struct promote_to_larger
{
typedef typename boost::mpl::deref<Iterator>::type current_type;
typedef typename boost::mpl::if_c
<
(bit_size<current_type>::type::value >= MinSize),
current_type,
typename promote_to_larger
<
T,
typename boost::mpl::next<Iterator>::type,
EndIterator,
MinSize
>::type
>::type type;
};
// The following specialization is required to finish the loop over
// all list elements
template <typename T, typename EndIterator, std::size_t MinSize>
struct promote_to_larger<T, EndIterator, EndIterator, MinSize>
{
// if promotion fails, keep the number T
// (and cross fingers that overflow will not occur)
typedef T type;
};
}} // namespace detail::promote_integral
#endif // DOXYGEN_NO_DETAIL
/*!
\brief Meta-function to define an integral type with size
than is (roughly) twice the bit size of T
\ingroup utility
\details
This meta-function tries to promote the fundamental integral type T
to a another integral type with size (roughly) twice the bit size of T.
To do this, two times the bit size of T is tested against the bit sizes of:
short, int, long, boost::long_long_type, boost::int128_t
and the one that first matches is chosen.
For unsigned types the bit size of T is tested against the bit
sizes of the types above, if T is promoted to a signed type, or
the bit sizes of
unsigned short, unsigned int, unsigned long, std::size_t,
boost::ulong_long_type, boost::uint128_t
if T is promoted to an unsigned type.
By default an unsigned type is promoted to a signed type.
This behavior is controlled by the PromoteUnsignedToUnsigned
boolean template parameter, whose default value is "false".
To promote an unsigned type to an unsigned type set the value of
this template parameter to "true".
If the macro BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER is not
defined, boost's multiprecision integer cpp_int<> is used as a
last resort.
If BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER is defined and an
appropriate type cannot be detected, the input type is returned as is.
Finally, if the passed type is either a floating-point type or a
user-defined type it is returned as is.
\note boost::long_long_type and boost::ulong_long_type are
considered only if the macro BOOST_HAS_LONG_LONG is defined
\note boost::int128_type and boost::uint128_type are considered
only if the macros BOOST_HAS_INT128 and BOOST_GEOMETRY_ENABLE_INT128
are defined
*/
template
<
typename T,
bool PromoteUnsignedToUnsigned = false,
bool UseCheckedInteger = false,
bool IsIntegral = boost::is_integral<T>::type::value
>
class promote_integral
{
private:
static bool const is_unsigned = boost::is_unsigned<T>::type::value;
typedef detail::promote_integral::bit_size<T> bit_size_type;
#if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
// Define the proper check policy for the multiprecision integer
typedef typename boost::mpl::if_c
<
UseCheckedInteger,
boost::integral_constant
<
boost::multiprecision::cpp_int_check_type,
boost::multiprecision::checked
>,
boost::integral_constant
<
boost::multiprecision::cpp_int_check_type,
boost::multiprecision::unchecked
>
>::type check_policy_type;
// Meta-function to get the multiprecision integer type for the
// given size and sign type (signed/unsigned)
template
<
unsigned int Size,
boost::multiprecision::cpp_integer_type SignType
>
struct multiprecision_integer_type
{
typedef boost::multiprecision::number
<
boost::multiprecision::cpp_int_backend
<
Size,
Size,
SignType,
check_policy_type::value,
void
>
> type;
};
#endif
// Define the minimum size (in bits) needed for the promoted type
// If T is the input type and P the promoted type, then the
// minimum number of bits for P are (below b stands for the number
// of bits of T):
// * if T is unsigned and P is unsigned: 2 * b
// * if T is signed and P is signed: 2 * b - 1
// * if T is unsigned and P is signed: 2 * b + 1
typedef typename boost::mpl::if_c
<
(PromoteUnsignedToUnsigned && is_unsigned),
boost::mpl::size_t<(2 * bit_size_type::value)>,
typename boost::mpl::if_c
<
is_unsigned,
boost::mpl::size_t<(2 * bit_size_type::value + 1)>,
boost::mpl::size_t<(2 * bit_size_type::value - 1)>
>::type
>::type min_bit_size_type;
// Define the list of signed integral types we are going to use
// for promotion
typedef boost::mpl::list
<
short, int, long
#if defined(BOOST_HAS_LONG_LONG)
, boost::long_long_type
#endif
#if defined(BOOST_HAS_INT128) && defined(BOOST_GEOMETRY_ENABLE_INT128)
, boost::int128_type
#endif
#if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
, typename multiprecision_integer_type
<
min_bit_size_type::value,
boost::multiprecision::signed_magnitude
>::type
#endif
> signed_integral_types;
// Define the list of unsigned integral types we are going to use
// for promotion
typedef boost::mpl::list
<
unsigned short, unsigned int, unsigned long, std::size_t
#if defined(BOOST_HAS_LONG_LONG)
, boost::ulong_long_type
#endif
#if defined(BOOST_HAS_INT128) && defined(BOOST_GEOMETRY_ENABLE_INT128)
, boost::uint128_type
#endif
#if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
, typename multiprecision_integer_type
<
min_bit_size_type::value,
boost::multiprecision::unsigned_magnitude
>::type
#endif
> unsigned_integral_types;
// Define the list of integral types that will be used for
// promotion (depending in whether we was to promote unsigned to
// unsigned or not)
typedef typename boost::mpl::if_c
<
(is_unsigned && PromoteUnsignedToUnsigned),
unsigned_integral_types,
signed_integral_types
>::type integral_types;
public:
typedef typename detail::promote_integral::promote_to_larger
<
T,
typename boost::mpl::begin<integral_types>::type,
typename boost::mpl::end<integral_types>::type,
min_bit_size_type::value
>::type type;
};
template <typename T, bool PromoteUnsignedToUnsigned, bool UseCheckedInteger>
class promote_integral
<
T, PromoteUnsignedToUnsigned, UseCheckedInteger, false
>
{
public:
typedef T type;
};
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_UTIL_PROMOTE_INTEGRAL_HPP

Some files were not shown because too many files have changed in this diff Show More