Merge branch 'develop' of https://github.com/boostorg/geometry into feature/disjoint
@@ -57,7 +57,6 @@ ALIASES = qbk{1}="\xmlonly <qbk>\1</qbk> \endxmlonly" \
|
||||
tparam_radius="numeric type for radius (of sphere, earth)" \
|
||||
tparam_container="container type, for example std::vector, std::deque" \
|
||||
tparam_dimension_required="Dimension, this template parameter is required. Should contain \\[0 .. n-1\\] for an n-dimensional geometry" \
|
||||
tparam_first_point="first point type" \
|
||||
tparam_functor="Function or class with operator()" \
|
||||
tparam_output_collection="output collection, either a multi-geometry, or a std::vector<Geometry> / std::deque<Geometry> etc" \
|
||||
tparam_geometry="Any type fulfilling a Geometry Concept" \
|
||||
@@ -67,8 +66,10 @@ ALIASES = qbk{1}="\xmlonly <qbk>\1</qbk> \endxmlonly" \
|
||||
tparam_out{1}="A valid output iterator type, accepting geometries of \1 Concept" \
|
||||
tparam_point="Any type fulfilling a Point Concept" \
|
||||
tparam_range_point="Any type fulfilling a Range Concept where it range_value type fulfills the Point Concept" \
|
||||
tparam_first_point="point type" \
|
||||
tparam_first_point="first point type" \
|
||||
tparam_first_box="first box type" \
|
||||
tparam_second_point="second point type" \
|
||||
tparam_second_box="second box type" \
|
||||
tparam_segment_point="segment point type" \
|
||||
tparam_strategy{1}="Any type fulfilling a \1 Strategy Concept" \
|
||||
tparam_strategy_overlay="Compound strategy for segment intersection" \
|
||||
@@ -176,9 +177,13 @@ WARN_LOGFILE =
|
||||
INPUT = . .. ../../../../boost/geometry/core \
|
||||
../../../../boost/geometry/algorithms \
|
||||
../../../../boost/geometry/algorithms/detail \
|
||||
../../../../boost/geometry/algorithms/detail/overlay \
|
||||
../../../../boost/geometry/algorithms/detail/distance \
|
||||
../../../../boost/geometry/algorithms/detail/equals \
|
||||
../../../../boost/geometry/algorithms/detail/overlay \
|
||||
../../../../boost/geometry/algorithms/detail/relate \
|
||||
../../../../boost/geometry/algorithms/detail/sections \
|
||||
../../../../boost/geometry/algorithms/detail/turns \
|
||||
../../../../boost/geometry/algorithms/detail/within \
|
||||
../../../../boost/geometry/arithmetic \
|
||||
../../../../boost/geometry/geometries/concepts \
|
||||
../../../../boost/geometry/geometries \
|
||||
|
||||
@@ -113,6 +113,7 @@ Boost.Geometry contains contributions by:
|
||||
* Federico Fern\u00E1ndez (preliminary version of R-tree spatial index)
|
||||
* Karsten Ahnert (patch for cross-track distance)
|
||||
* Mats Taraldsvik (documentation: adapting a legacy model)
|
||||
* Samuel Debionne (variant support for distance)
|
||||
|
||||
[include imports.qbk]
|
||||
|
||||
|
||||
BIN
doc/html/img/index/rtree/knn_box_box.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
doc/html/img/index/rtree/knn_pt_box.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
doc/html/img/index/rtree/knn_seg_box.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
doc/html/img/index/rtree/rtree_pt.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
doc/html/img/index/rtree/rtree_pt_disjoint_box.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
doc/html/img/index/rtree/rtree_pt_intersects_box.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
doc/html/img/index/rtree/rtree_pt_knn_box.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
doc/html/img/index/rtree/rtree_pt_knn_pt.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
doc/html/img/index/rtree/rtree_pt_knn_seg.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
doc/html/img/index/rtree/rtree_seg.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
doc/html/img/index/rtree/rtree_seg_disjoint_box.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
doc/html/img/index/rtree/rtree_seg_intersects_box.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
doc/html/img/index/rtree/rtree_seg_knn_box.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
doc/html/img/index/rtree/rtree_seg_knn_pt.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
doc/html/img/index/rtree/rtree_seg_knn_seg.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
@@ -105,6 +105,8 @@
|
||||
[import src/examples/geometries/register/multi_polygon.cpp]
|
||||
|
||||
[import src/examples/io/svg.cpp]
|
||||
[import src/examples/io/wkt.cpp]
|
||||
[import src/examples/io/read_wkt.cpp]
|
||||
|
||||
[import src/examples/views/box_view.cpp]
|
||||
[import src/examples/views/segment_view.cpp]
|
||||
|
||||
@@ -51,7 +51,7 @@ The examples of structures of trees created by use of different algorithms and e
|
||||
[table
|
||||
[[] [Linear algorithm] [Quadratic algorithm] [R*-tree] [Packing algorithm]]
|
||||
[[*Example structure*] [[$img/index/rtree/linear.png]] [[$img/index/rtree/quadratic.png]] [[$img/index/rtree/rstar.png]] [[$img/index/rtree/bulk.png]]]
|
||||
[[*1M Values inserts*] [1.76s] [2.47s] [6.19s] [1.67s]]
|
||||
[[*1M Values inserts*] [1.76s] [2.47s] [6.19s] [0.64s]]
|
||||
[[*100k spatial queries*] [2.21s] [0.51s] [0.12s] [0.07s]]
|
||||
[[*100k knn queries*] [6.37s] [2.09s] [0.64s] [0.52s]]
|
||||
]
|
||||
|
||||
@@ -30,13 +30,20 @@ __rtree__ has 5 parameters but only 2 are required:
|
||||
|
||||
__rtree__ may store `__value__`s of any type as long as passed function objects know how to interpret those `__value__`s, that is
|
||||
extract an `__indexable__` that the __rtree__ can handle and compare `__value__`s.
|
||||
The `__indexable__` is a type adapted to Point, Box or Segment concept.
|
||||
The examples of rtrees storing `__value__`s translatable to various `__indexable__`s are presented below.
|
||||
|
||||
[table
|
||||
[[rtree<Point, ...>] [rtree<Box, ...>] [rtree<Segment, ...>]]
|
||||
[[[$img/index/rtree/rtree_pt.png]] [[$img/index/rtree/rstar.png]] [[$img/index/rtree/rtree_seg.png]]]
|
||||
]
|
||||
|
||||
By default function objects `index::indexable<Value>` and `index::equal_to<Value>` are defined for some typically used `__value__`
|
||||
types which may be stored without defining any additional classes. By default the rtree may store pure `__indexable__`s, pairs
|
||||
and tuples. In the case of those two collection types, the `__indexable__` must be the first stored type.
|
||||
|
||||
* `__indexable__ = __point__ | __box__`
|
||||
* `__value__ = Indexable | std::pair<__indexable__, T> | tuple<__indexable__, ...>`
|
||||
* `__indexable__ = __point__ | __box__ | Segment`
|
||||
* `__value__ = Indexable | std::pair<__indexable__, T> | boost::tuple<__indexable__, ...> [ | std::tuple<__indexable__, ...> ]`
|
||||
|
||||
By default `boost::tuple<...>` is supported on all compilers. If the compiler supports C++11 tuples and variadic templates
|
||||
then `std::tuple<...>` may be used "out of the box" as well.
|
||||
@@ -46,6 +53,7 @@ Examples of default `__value__` types:
|
||||
geometry::model::point<...>
|
||||
geometry::model::point_xy<...>
|
||||
geometry::model::box<...>
|
||||
geometry::model::segment<...>
|
||||
std::pair<geometry::model::box<...>, unsigned>
|
||||
boost::tuple<geometry::model::point<...>, int, float>
|
||||
|
||||
@@ -55,7 +63,7 @@ The predefined `index::indexable<Value>` returns const reference to the `__index
|
||||
|
||||
The predefined `index::equal_to<Value>`:
|
||||
|
||||
* for `__point__` and `__box__` - compares `__value__`s with geometry::equals().
|
||||
* for `__point__`, `__box__` and `Segment` - compares `__value__`s with geometry::equals().
|
||||
* for `std::pair<...>` - compares both components of the `__value__`. The first value stored in the pair is compared before the second one.
|
||||
If the value stored in the pair is a Geometry, `geometry::equals()` is used. For other types it uses `operator==()`.
|
||||
* for `tuple<...>` - compares all components of the `__value__`. If the component is a `Geometry`, `geometry::equals()`
|
||||
|
||||
@@ -73,6 +73,11 @@ Examples of some basic queries may be found in the tables below. The query regio
|
||||
[[[$img/index/rtree/intersects_ring.png]] [[$img/index/rtree/intersects_poly.png]] [[$img/index/rtree/intersects_mpoly.png]] [[$img/index/rtree/intersects_segment.png]] [[$img/index/rtree/intersects_linestring.png]]]
|
||||
]
|
||||
|
||||
[table
|
||||
[[intersects(Box)] [disjoint(Box)] [intersects(Box)] [disjoint(Box)]]
|
||||
[[[$img/index/rtree/rtree_pt_intersects_box.png]] [[$img/index/rtree/rtree_pt_disjoint_box.png]] [[$img/index/rtree/rtree_seg_intersects_box.png]] [[$img/index/rtree/rtree_seg_disjoint_box.png]]]
|
||||
]
|
||||
|
||||
Spatial predicates are generated by functions defined in `boost::geometry::index` namespace.
|
||||
|
||||
rt.query(index::contains(box), std::back_inserter(result));
|
||||
@@ -91,20 +96,36 @@ All spatial predicates may be negated, e.g.:
|
||||
|
||||
[h4 Nearest neighbours queries]
|
||||
|
||||
Nearest neighbours queries returns `__value__`s which are closest to some point in space.
|
||||
The example of k-NN query is presented below. 5 `__value__`s nearest to the point are orange.
|
||||
Nearest neighbours queries returns `__value__`s which are closest to some Geometry.
|
||||
The examples of k-NN queries are presented below. 5 `__value__`s nearest to the Geometry are orange.
|
||||
|
||||
[$img/index/rtree/knn.png]
|
||||
[table
|
||||
[[nearest(Point, k)] [nearest(Box, k)] [nearest(Segment, k)]]
|
||||
[[[$img/index/rtree/knn_pt_box.png]] [[$img/index/rtree/knn_box_box.png]] [[$img/index/rtree/knn_seg_box.png]]]
|
||||
]
|
||||
[table
|
||||
[[nearest(Point, k)] [nearest(Box, k)] [nearest(Segment, k)] [nearest(Point, k)] [nearest(Box, k)] [nearest(Segment, k)]]
|
||||
[[[$img/index/rtree/rtree_pt_knn_pt.png]] [[$img/index/rtree/rtree_pt_knn_box.png]] [[$img/index/rtree/rtree_pt_knn_seg.png]]
|
||||
[[$img/index/rtree/rtree_seg_knn_pt.png]] [[$img/index/rtree/rtree_seg_knn_box.png]] [[$img/index/rtree/rtree_seg_knn_seg.png]]]
|
||||
]
|
||||
|
||||
To perform the knn query one must pass the nearest predicate generated by the
|
||||
`nearest()` function defined in `boost::geometry::index` namespace.
|
||||
The following query returns `k` `__value__`s closest to some point in space.
|
||||
For non-point `__indexable__`s the shortest distance is calculated.
|
||||
For non-point `__indexable__`s the shortest distance is calculated using `bg::comparable_distance()` function.
|
||||
The following query returns `k` `__value__`s closest to some Point in space.
|
||||
|
||||
std::vector<__value__> returned_values;
|
||||
__point__ pt(...);
|
||||
__point__ pt(/*...*/);
|
||||
rt.query(bgi::nearest(pt, k), std::back_inserter(returned_values));
|
||||
|
||||
The same way different query Geometries can be used:
|
||||
|
||||
__box__ box(/*...*/);
|
||||
rt.query(bgi::nearest(box, k), std::back_inserter(returned_values));
|
||||
|
||||
Segment seg(/*...*/);
|
||||
rt.query(bgi::nearest(seg, k), std::back_inserter(returned_values));
|
||||
|
||||
[h4 User-defined unary predicate]
|
||||
|
||||
The user may pass a `UnaryPredicate` - function, function object or lambda expression taking const reference to Value and returning bool.
|
||||
|
||||
@@ -741,7 +741,7 @@
|
||||
<member><link linkend="geometry.reference.spatial_indexes.group__predicates.overlaps_geometry_const___">overlaps(Geometry const &)</link></member>
|
||||
<member><link linkend="geometry.reference.spatial_indexes.group__predicates.within_geometry_const___">within(Geometry const &)</link></member>
|
||||
<member><link linkend="geometry.reference.spatial_indexes.group__predicates.satisfies_unarypredicate_const___">satisfies(UnaryPredicate const &)</link></member>
|
||||
<member><link linkend="geometry.reference.spatial_indexes.group__predicates.nearest_point_const____unsigned_">nearest(Point const &, unsigned)</link></member>
|
||||
<member><link linkend="geometry.reference.spatial_indexes.group__predicates.nearest_geometry_const____unsigned_">nearest(Geometry const &, unsigned)</link></member>
|
||||
</simplelist>
|
||||
</entry>
|
||||
<!--entry valign="top">
|
||||
|
||||
@@ -223,7 +223,7 @@
|
||||
|
||||
[section:io IO (input/output)]
|
||||
[section:wkt WKT (Well-Known Text)]
|
||||
[/include generated/wkt.qbk/]
|
||||
[include generated/wkt.qbk]
|
||||
[endsect]
|
||||
[section:svg SVG (Scalable Vector Graphics)]
|
||||
[include generated/svg.qbk]
|
||||
|
||||
15
doc/reference/io/read_wkt.qbk
Normal file
@@ -0,0 +1,15 @@
|
||||
[/============================================================================
|
||||
Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
Copyright (c) 2009-2014 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)
|
||||
=============================================================================/]
|
||||
|
||||
[heading Example]
|
||||
[read_wkt]
|
||||
|
||||
[heading See also]
|
||||
* [link geometry.reference.io.wkt.wkt WKT streaming manipulator]
|
||||
16
doc/reference/io/wkt.qbk
Normal file
@@ -0,0 +1,16 @@
|
||||
[/============================================================================
|
||||
Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
Copyright (c) 2009-2014 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)
|
||||
=============================================================================/]
|
||||
|
||||
[heading Example]
|
||||
[wkt]
|
||||
[wkt_output]
|
||||
|
||||
[heading See also]
|
||||
* [link geometry.reference.io.wkt.read_wkt Read WKT]
|
||||
@@ -18,4 +18,5 @@ exe quick_start : quick_start.cpp ;
|
||||
build-project algorithms ;
|
||||
build-project core ;
|
||||
build-project geometries ;
|
||||
build-project io ;
|
||||
build-project views ;
|
||||
|
||||
19
doc/src/examples/io/Jamfile.v2
Normal file
@@ -0,0 +1,19 @@
|
||||
# Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
#
|
||||
# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
# Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
|
||||
# Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
# Copyright (c) 2013-2014 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)
|
||||
|
||||
|
||||
project boost-geometry-doc-example-io
|
||||
: # requirements
|
||||
;
|
||||
|
||||
exe svg : svg.cpp ;
|
||||
exe wkt : wkt.cpp ;
|
||||
exe read_wkt : read_wkt.cpp ;
|
||||
37
doc/src/examples/io/read_wkt.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// QuickBook Example
|
||||
|
||||
// Copyright (c) 2014 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)
|
||||
|
||||
//[read_wkt
|
||||
//` Shows the usage of read_wkt
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/geometry.hpp>
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
#include <boost/geometry/geometries/polygon.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
// Specify the basic type
|
||||
typedef boost::geometry::model::d2::point_xy<double> point_type;
|
||||
|
||||
// Declare some geometries and set their values
|
||||
point_type a;
|
||||
boost::geometry::model::polygon<point_type> b;
|
||||
|
||||
boost::geometry::read_wkt("POINT(1 2)", a);
|
||||
boost::geometry::read_wkt("POLYGON((0 0,0 7,4 2,2 0,0 0))", b);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//]
|
||||
|
||||
43
doc/src/examples/io/wkt.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// QuickBook Example
|
||||
|
||||
// Copyright (c) 2014 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)
|
||||
|
||||
//[wkt
|
||||
//` Shows the usage of wkt
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/geometry.hpp>
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
#include <boost/geometry/geometries/polygon.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
// Specify the basic type
|
||||
typedef boost::geometry::model::d2::point_xy<double> point_type;
|
||||
|
||||
// Declare some geometries and set their values
|
||||
point_type a;
|
||||
boost::geometry::assign_values(a, 3, 6);
|
||||
|
||||
std::cout << boost::geometry::wkt(a) << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//]
|
||||
|
||||
|
||||
//[wkt_output
|
||||
/*`
|
||||
Output:
|
||||
point(3 6)
|
||||
|
||||
*/
|
||||
//]
|
||||
@@ -273,6 +273,13 @@ void test_all()
|
||||
"POLYGON((5 0,2.5 9,9.5 3.5,0.5 3.5,7.5 9,5 0))",
|
||||
0, 11, 25.6158412);
|
||||
|
||||
// CCW polygons should turn CW after dissolve
|
||||
test_one<polygon, polygon>("cw",
|
||||
"POLYGON((2 8,8 8,8 0,0 0,0 6,4 6,4 4,2 4,2 8))",
|
||||
0, 7, 60);
|
||||
test_one<polygon, polygon>("ccw",
|
||||
"POLYGON((2 8,2 4,4 4,4 6,0 6,0 0,8 0,8 8,2 8))",
|
||||
0, 12, 64); // TODO: should have the same, 7, 60. The polygon is dissolved (splitted) but the extra polygon is still on top of the other
|
||||
|
||||
// Multi-geometries
|
||||
{
|
||||
|
||||
@@ -86,13 +86,17 @@ private:
|
||||
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
comparable_strategy, Point, typename point_type<Range>::type
|
||||
comparable_strategy,
|
||||
Point,
|
||||
typename boost::range_value<Range>::type
|
||||
>::type comparable_return_type;
|
||||
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy, Point, typename point_type<Range>::type
|
||||
Strategy,
|
||||
Point,
|
||||
typename boost::range_value<Range>::type
|
||||
>::type return_type;
|
||||
|
||||
static inline return_type apply(Point const& point, Range const& range,
|
||||
@@ -123,7 +127,8 @@ public:
|
||||
{
|
||||
return strategy::distance::services::comparable_to_regular
|
||||
<
|
||||
comparable_strategy, Strategy, Point, Range
|
||||
comparable_strategy, Strategy, Point,
|
||||
typename boost::range_value<Range>::type
|
||||
>::apply( c_strategy.apply(point,
|
||||
*boost::begin(view),
|
||||
*boost::begin(view)) );
|
||||
@@ -140,7 +145,10 @@ public:
|
||||
{
|
||||
return strategy::distance::services::comparable_to_regular
|
||||
<
|
||||
comparable_strategy, Strategy, Point, Range
|
||||
comparable_strategy,
|
||||
Strategy,
|
||||
Point,
|
||||
typename boost::range_value<Range>::type
|
||||
>::apply(zero);
|
||||
}
|
||||
else if (cds < cd)
|
||||
@@ -151,7 +159,10 @@ public:
|
||||
|
||||
return strategy::distance::services::comparable_to_regular
|
||||
<
|
||||
comparable_strategy, Strategy, Point, Range
|
||||
comparable_strategy,
|
||||
Strategy,
|
||||
Point,
|
||||
typename boost::range_value<Range>::type
|
||||
>::apply(cd);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -127,23 +127,10 @@ private:
|
||||
BoxPoints const& box_points,
|
||||
ComparableStrategy const& strategy)
|
||||
{
|
||||
boost::ignore_unused_variable_warning(strategy);
|
||||
|
||||
comparable_return_type cd_min =
|
||||
strategy.apply(point, box_points[0], box_points[3]);
|
||||
|
||||
for (unsigned int i = 0; i < 2; ++i)
|
||||
{
|
||||
comparable_return_type cd =
|
||||
strategy.apply(point, box_points[i], box_points[i+1]);
|
||||
|
||||
if ( cd < cd_min )
|
||||
{
|
||||
cd_min = cd;
|
||||
}
|
||||
}
|
||||
|
||||
return cd_min;
|
||||
return point_to_range
|
||||
<
|
||||
Point, BoxPoints, open, ComparableStrategy
|
||||
>::apply(point, box_points, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_BOX_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_BOX_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
@@ -29,11 +31,14 @@
|
||||
|
||||
#include <boost/geometry/policies/compare.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/equals.hpp>
|
||||
#include <boost/geometry/algorithms/intersects.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
|
||||
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/point_to_geometry.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/distance.hpp>
|
||||
|
||||
@@ -48,6 +53,165 @@ namespace detail { namespace distance
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment,
|
||||
typename Box,
|
||||
typename Strategy,
|
||||
bool UsePointBoxStrategy = false
|
||||
>
|
||||
class segment_to_box_2D_generic
|
||||
{
|
||||
private:
|
||||
typedef typename point_type<Segment>::type segment_point;
|
||||
typedef typename point_type<Box>::type box_point;
|
||||
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
<
|
||||
Strategy
|
||||
>::type comparable_strategy;
|
||||
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
comparable_strategy, segment_point, box_point
|
||||
>::type comparable_return_type;
|
||||
|
||||
typedef point_to_range
|
||||
<
|
||||
segment_point, std::vector<box_point>, open, comparable_strategy
|
||||
> point_to_box_boundary;
|
||||
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy, segment_point, box_point
|
||||
>::type return_type;
|
||||
|
||||
static inline return_type apply(Segment const& segment,
|
||||
Box const& box,
|
||||
Strategy const& strategy,
|
||||
bool check_intersection = true)
|
||||
{
|
||||
if ( check_intersection && geometry::intersects(segment, box) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
comparable_strategy cstrategy =
|
||||
strategy::distance::services::get_comparable
|
||||
<
|
||||
Strategy
|
||||
>::apply(strategy);
|
||||
boost::ignore_unused_variable_warning(cstrategy);
|
||||
|
||||
// get segment points
|
||||
segment_point p[2];
|
||||
detail::assign_point_from_index<0>(segment, p[0]);
|
||||
detail::assign_point_from_index<1>(segment, p[1]);
|
||||
|
||||
// get box points
|
||||
std::vector<box_point> box_points(4);
|
||||
detail::assign_box_corners_oriented<true>(box, box_points);
|
||||
|
||||
comparable_return_type cd[6];
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
{
|
||||
cd[i] = cstrategy.apply(box_points[i], p[0], p[1]);
|
||||
}
|
||||
cd[4] = point_to_box_boundary::apply(p[0], box_points, cstrategy);
|
||||
cd[5] = point_to_box_boundary::apply(p[1], box_points, cstrategy);
|
||||
|
||||
return strategy::distance::services::comparable_to_regular
|
||||
<
|
||||
comparable_strategy, Strategy, Segment, Box
|
||||
>::apply( *std::min_element(cd, cd + 6) );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment,
|
||||
typename Box,
|
||||
typename Strategy
|
||||
>
|
||||
class segment_to_box_2D_generic<Segment, Box, Strategy, true>
|
||||
{
|
||||
private:
|
||||
typedef typename point_type<Segment>::type segment_point;
|
||||
typedef typename point_type<Box>::type box_point;
|
||||
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
<
|
||||
Strategy
|
||||
>::type comparable_strategy;
|
||||
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
comparable_strategy, segment_point, box_point
|
||||
>::type comparable_return_type;
|
||||
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
<
|
||||
typename detail::distance::default_strategy
|
||||
<
|
||||
segment_point, Box
|
||||
>::type
|
||||
>::type point_box_comparable_strategy;
|
||||
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy, segment_point, box_point
|
||||
>::type return_type;
|
||||
|
||||
static inline return_type apply(Segment const& segment,
|
||||
Box const& box,
|
||||
Strategy const& strategy,
|
||||
bool check_intersection = true)
|
||||
{
|
||||
if ( check_intersection && geometry::intersects(segment, box) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
comparable_strategy cstrategy =
|
||||
strategy::distance::services::get_comparable
|
||||
<
|
||||
Strategy
|
||||
>::apply(strategy);
|
||||
boost::ignore_unused_variable_warning(cstrategy);
|
||||
|
||||
// get segment points
|
||||
segment_point p[2];
|
||||
detail::assign_point_from_index<0>(segment, p[0]);
|
||||
detail::assign_point_from_index<1>(segment, p[1]);
|
||||
|
||||
// get box points
|
||||
std::vector<box_point> box_points(4);
|
||||
detail::assign_box_corners_oriented<true>(box, box_points);
|
||||
|
||||
comparable_return_type cd[6];
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
{
|
||||
cd[i] = cstrategy.apply(box_points[i], p[0], p[1]);
|
||||
}
|
||||
|
||||
point_box_comparable_strategy pb_cstrategy;
|
||||
boost::ignore_unused_variable_warning(pb_cstrategy);
|
||||
cd[4] = pb_cstrategy.apply(p[0], box);
|
||||
cd[5] = pb_cstrategy.apply(p[1], box);
|
||||
|
||||
return strategy::distance::services::comparable_to_regular
|
||||
<
|
||||
comparable_strategy, Strategy, Segment, Box
|
||||
>::apply( *std::min_element(cd, cd + 6) );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename ReturnType,
|
||||
@@ -118,7 +282,7 @@ private:
|
||||
}
|
||||
|
||||
// p1 lies to the left of the box
|
||||
if ( geometry::get<0>(p1) <= geometry::get<1>(bottom_left) )
|
||||
if ( geometry::get<0>(p1) <= geometry::get<0>(bottom_left) )
|
||||
{
|
||||
if ( geometry::get<1>(p1) <= geometry::get<1>(bottom_left) )
|
||||
{
|
||||
@@ -253,7 +417,7 @@ private:
|
||||
}
|
||||
|
||||
// p1 lies to the left of the box
|
||||
if ( geometry::get<0>(p1) <= geometry::get<1>(bottom_left) )
|
||||
if ( geometry::get<0>(p1) <= geometry::get<0>(bottom_left) )
|
||||
{
|
||||
if ( geometry::get<1>(p1) >= geometry::get<1>(top_left) )
|
||||
{
|
||||
@@ -322,9 +486,9 @@ private:
|
||||
ReturnType diff1 = cast::apply(geometry::get<1>(p0))
|
||||
- cast::apply(geometry::get<1>(p1));
|
||||
ReturnType t_min1 = cast::apply(geometry::get<1>(p0))
|
||||
- cast::apply(geometry::get<1>(top_right));
|
||||
ReturnType t_max1 = cast::apply(geometry::get<1>(p0))
|
||||
- cast::apply(geometry::get<1>(bottom_left));
|
||||
ReturnType t_max1 = cast::apply(geometry::get<1>(p0))
|
||||
- cast::apply(geometry::get<1>(top_right));
|
||||
|
||||
// t_max0 < t_max1
|
||||
if ( t_max0 * diff1 < t_max1 * diff0 )
|
||||
|
||||
@@ -38,8 +38,8 @@ struct get_turn_without_info
|
||||
{
|
||||
template <typename RobustPolicy, typename OutputIterator>
|
||||
static inline OutputIterator apply(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& /*pk*/,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& /*qk*/,
|
||||
bool /*is_p_first*/, bool /*is_p_last*/,
|
||||
bool /*is_q_first*/, bool /*is_q_last*/,
|
||||
TurnInfo const& ,
|
||||
|
||||
@@ -394,8 +394,8 @@ struct get_turn_info_for_endpoint
|
||||
typename TurnInfo,
|
||||
typename IntersectionInfo
|
||||
>
|
||||
static inline bool handle_internal(Point1 const& i1, Point1 const& j1, Point1 const& /*k1*/,
|
||||
Point2 const& i2, Point2 const& j2, Point2 const& k2,
|
||||
static inline bool handle_internal(Point1 const& /*i1*/, Point1 const& /*j1*/, Point1 const& /*k1*/,
|
||||
Point2 const& i2, Point2 const& j2, Point2 const& /*k2*/,
|
||||
RobustPoint1 const& ri1, RobustPoint1 const& rj1, RobustPoint1 const& /*rk1*/,
|
||||
RobustPoint2 const& ri2, RobustPoint2 const& rj2, RobustPoint2 const& rk2,
|
||||
bool first1, bool last1, bool first2, bool last2,
|
||||
@@ -403,6 +403,8 @@ struct get_turn_info_for_endpoint
|
||||
IntersectionInfo const& inters, int ip_index,
|
||||
operation_type & op1, operation_type & op2)
|
||||
{
|
||||
boost::ignore_unused_variable_warning(i2);
|
||||
boost::ignore_unused_variable_warning(j2);
|
||||
boost::ignore_unused_variable_warning(ip_index);
|
||||
boost::ignore_unused_variable_warning(tp_model);
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ public:
|
||||
|
||||
intersection_info_base(Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
no_rescale_policy const& robust_policy)
|
||||
no_rescale_policy const& /*robust_policy*/)
|
||||
: m_side_calc(pi, pj, pk, qi, qj, qk)
|
||||
{}
|
||||
|
||||
|
||||
@@ -446,7 +446,7 @@ struct get_turn_info_linear_areal
|
||||
typename OutIt>
|
||||
static inline bool append_collinear_spikes(TurnInfo & tp,
|
||||
IntersectionInfo const& inters,
|
||||
bool is_p_last, bool is_q_last,
|
||||
bool is_p_last, bool /*is_q_last*/,
|
||||
method_type method, append_version_c version,
|
||||
OutIt out)
|
||||
{
|
||||
@@ -489,7 +489,7 @@ struct get_turn_info_linear_areal
|
||||
typename OutIt>
|
||||
static inline bool append_opposite_spikes(TurnInfo & tp,
|
||||
IntersectionInfo const& inters,
|
||||
bool is_p_last, bool is_q_last,
|
||||
bool is_p_last, bool /*is_q_last*/,
|
||||
OutIt out)
|
||||
{
|
||||
bool is_p_spike = ( Version == append_touches ?
|
||||
@@ -635,10 +635,10 @@ struct get_turn_info_linear_areal
|
||||
typename IntersectionInfo,
|
||||
typename OutputIterator>
|
||||
static inline bool get_turn_info_for_endpoint(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
Point1 const& pi, Point1 const& /*pj*/, Point1 const& /*pk*/,
|
||||
Point2 const& qi, Point2 const& /*qj*/, Point2 const& /*qk*/,
|
||||
bool is_p_first, bool is_p_last,
|
||||
bool is_q_first, bool is_q_last,
|
||||
bool /*is_q_first*/, bool is_q_last,
|
||||
TurnInfo const& tp_model,
|
||||
IntersectionInfo const& inters,
|
||||
method_type /*method*/,
|
||||
@@ -659,6 +659,8 @@ struct get_turn_info_linear_areal
|
||||
if ( !is_p_first && !is_p_last )
|
||||
return false;
|
||||
|
||||
// TODO: is_q_last could probably be replaced by false and removed from parameters
|
||||
|
||||
linear_intersections intersections(pi, qi, inters.result(), is_p_last, is_q_last);
|
||||
linear_intersections::ip_info const& ip0 = intersections.template get<0>();
|
||||
linear_intersections::ip_info const& ip1 = intersections.template get<1>();
|
||||
|
||||
@@ -464,14 +464,11 @@ struct linear_areal
|
||||
typename Geometry,
|
||||
typename OtherGeometry,
|
||||
typename BoundaryChecker>
|
||||
void apply(Result & res,
|
||||
TurnIt first, TurnIt it, TurnIt last,
|
||||
void apply(Result & res, TurnIt it,
|
||||
Geometry const& geometry,
|
||||
OtherGeometry const& other_geometry,
|
||||
BoundaryChecker const& boundary_checker)
|
||||
{
|
||||
//BOOST_ASSERT( it != last );
|
||||
|
||||
overlay::operation_type op = it->operations[op_id].operation;
|
||||
|
||||
if ( op != overlay::operation_union
|
||||
@@ -769,7 +766,7 @@ struct linear_areal
|
||||
void apply(Result & res,
|
||||
TurnIt first, TurnIt last,
|
||||
Geometry const& geometry,
|
||||
OtherGeometry const& other_geometry,
|
||||
OtherGeometry const& /*other_geometry*/,
|
||||
BoundaryChecker const& boundary_checker)
|
||||
{
|
||||
//BOOST_ASSERT( first != last );
|
||||
@@ -966,7 +963,7 @@ struct linear_areal
|
||||
|
||||
for ( TurnIt it = first ; it != last ; ++it )
|
||||
{
|
||||
analyser.apply(res, first, it, last,
|
||||
analyser.apply(res, it,
|
||||
geometry, other_geometry,
|
||||
boundary_checker);
|
||||
|
||||
|
||||
@@ -257,15 +257,12 @@ struct linear_linear
|
||||
typename OtherGeometry,
|
||||
typename BoundaryChecker,
|
||||
typename OtherBoundaryChecker>
|
||||
void apply(Result & res,
|
||||
TurnIt first, TurnIt it, TurnIt last,
|
||||
void apply(Result & res, TurnIt it,
|
||||
Geometry const& geometry,
|
||||
OtherGeometry const& other_geometry,
|
||||
BoundaryChecker const& boundary_checker,
|
||||
OtherBoundaryChecker const& other_boundary_checker)
|
||||
{
|
||||
//BOOST_ASSERT( it != last );
|
||||
|
||||
overlay::operation_type op = it->operations[op_id].operation;
|
||||
|
||||
segment_identifier const& seg_id = it->operations[op_id].seg_id;
|
||||
@@ -563,7 +560,7 @@ struct linear_linear
|
||||
Geometry const& geometry,
|
||||
OtherGeometry const& /*other_geometry*/,
|
||||
BoundaryChecker const& boundary_checker,
|
||||
OtherBoundaryChecker const& other_boundary_checker)
|
||||
OtherBoundaryChecker const& /*other_boundary_checker*/)
|
||||
{
|
||||
//BOOST_ASSERT( first != last );
|
||||
|
||||
@@ -621,7 +618,7 @@ struct linear_linear
|
||||
Geometry const& geometry,
|
||||
OtherGeometry const& other_geometry,
|
||||
BoundaryChecker const& boundary_checker,
|
||||
OtherBoundaryChecker const& other_boundary_checker,
|
||||
OtherBoundaryChecker const& /*other_boundary_checker*/,
|
||||
bool first_in_range)
|
||||
{
|
||||
typename detail::single_geometry_return_type<Geometry const>::type
|
||||
@@ -747,7 +744,7 @@ struct linear_linear
|
||||
|
||||
for ( TurnIt it = first ; it != last ; ++it )
|
||||
{
|
||||
analyser.apply(res, first, it, last,
|
||||
analyser.apply(res, it,
|
||||
geometry, other_geometry,
|
||||
boundary_checker, other_boundary_checker);
|
||||
|
||||
|
||||
@@ -823,7 +823,7 @@ template <typename Last, char D, field F1, field F2>
|
||||
struct static_may_update_sequence<Last, Last, D, F1, F2>
|
||||
{
|
||||
template <typename Matrix>
|
||||
static inline bool apply(Matrix const& matrix)
|
||||
static inline bool apply(Matrix const& /*matrix*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -911,7 +911,7 @@ struct static_check_dispatch
|
||||
return el == mask_el;
|
||||
}
|
||||
// else
|
||||
static inline bool apply_dispatch(char el, integral_constant<int, 3>)
|
||||
static inline bool apply_dispatch(char /*el*/, integral_constant<int, 3>)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -943,7 +943,7 @@ template <typename Last>
|
||||
struct static_check_sequence<Last, Last>
|
||||
{
|
||||
template <typename Matrix>
|
||||
static inline bool apply(Matrix const& matrix)
|
||||
static inline bool apply(Matrix const& /*matrix*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -37,15 +37,17 @@ namespace boost { namespace geometry {
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace within {
|
||||
|
||||
// TODO: is this needed?
|
||||
inline int check_result_type(int result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void check_result_type(T result)
|
||||
inline T check_result_type(T result)
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Point, typename Range, typename Strategy> inline
|
||||
|
||||
@@ -54,7 +54,7 @@ struct fe_point_per_point
|
||||
struct fe_point_per_segment
|
||||
{
|
||||
template <typename Point, typename Functor>
|
||||
static inline void apply(Point& , Functor& f)
|
||||
static inline void apply(Point& , Functor& /*f*/)
|
||||
{
|
||||
// TODO: if non-const, we should extract the points from the segment
|
||||
// and call the functor on those two points
|
||||
|
||||
@@ -125,7 +125,12 @@ class plusmin_policy
|
||||
//negative = true;
|
||||
|
||||
typedef typename geometry::point_type<Geometry2>::type point_type;
|
||||
typedef overlay::turn_info<point_type> turn_info;
|
||||
|
||||
typedef overlay::turn_info
|
||||
<
|
||||
point_type,
|
||||
typename segment_ratio_type<point_type, RescalePolicy>::type
|
||||
> turn_info;
|
||||
std::deque<turn_info> turns;
|
||||
|
||||
// Get (and stop on) any intersection
|
||||
|
||||
@@ -294,7 +294,7 @@ private:
|
||||
inline static
|
||||
subtree_elements_counts calculate_subtree_elements_counts(std::size_t elements_count, parameters_type const& parameters, size_type & leafs_level)
|
||||
{
|
||||
(void)parameters;
|
||||
boost::ignore_unused_variable_warning(parameters);
|
||||
|
||||
subtree_elements_counts res(1, 1);
|
||||
leafs_level = 0;
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP
|
||||
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index { namespace detail {
|
||||
|
||||
namespace utilities {
|
||||
@@ -26,8 +28,16 @@ struct gl_draw_point<Point, 2>
|
||||
{
|
||||
static inline void apply(Point const& p, typename coordinate_type<Point>::type z)
|
||||
{
|
||||
glBegin(GL_POINT);
|
||||
glVertex3f(geometry::get<0>(p), geometry::get<1>(p), z);
|
||||
typename coordinate_type<Point>::type const& x = geometry::get<0>(p);
|
||||
typename coordinate_type<Point>::type const& y = geometry::get<1>(p);
|
||||
/*glBegin(GL_POINT);
|
||||
glVertex3f(x, y, z);
|
||||
glEnd();*/
|
||||
glBegin(GL_QUADS);
|
||||
glVertex3f(x+1, y, z);
|
||||
glVertex3f(x, y+1, z);
|
||||
glVertex3f(x-1, y, z);
|
||||
glVertex3f(x, y-1, z);
|
||||
glEnd();
|
||||
}
|
||||
};
|
||||
@@ -50,32 +60,42 @@ struct gl_draw_box<Box, 2>
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Segment, size_t Dimension>
|
||||
struct gl_draw_segment
|
||||
{};
|
||||
|
||||
template <typename Segment>
|
||||
struct gl_draw_segment<Segment, 2>
|
||||
{
|
||||
static inline void apply(Segment const& s, typename coordinate_type<Segment>::type z)
|
||||
{
|
||||
glBegin(GL_LINES);
|
||||
glVertex3f(geometry::get<0, 0>(s), geometry::get<0, 1>(s), z);
|
||||
glVertex3f(geometry::get<1, 0>(s), geometry::get<1, 1>(s), z);
|
||||
glEnd();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Indexable, typename Tag>
|
||||
struct gl_draw_indexable
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG((false), NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag));
|
||||
};
|
||||
|
||||
template <typename Indexable>
|
||||
struct gl_draw_indexable<Indexable, box_tag>
|
||||
{
|
||||
static const size_t dimension = geometry::dimension<Indexable>::value;
|
||||
template <typename Box>
|
||||
struct gl_draw_indexable<Box, box_tag>
|
||||
: gl_draw_box<Box, geometry::dimension<Box>::value>
|
||||
{};
|
||||
|
||||
static inline void apply(Indexable const& i, typename coordinate_type<Indexable>::type z)
|
||||
{
|
||||
gl_draw_box<Indexable, dimension>::apply(i, z);
|
||||
}
|
||||
};
|
||||
template <typename Point>
|
||||
struct gl_draw_indexable<Point, point_tag>
|
||||
: gl_draw_point<Point, geometry::dimension<Point>::value>
|
||||
{};
|
||||
|
||||
template <typename Indexable>
|
||||
struct gl_draw_indexable<Indexable, point_tag>
|
||||
{
|
||||
static const size_t dimension = geometry::dimension<Indexable>::value;
|
||||
|
||||
static inline void apply(Indexable const& i, typename coordinate_type<Indexable>::type z)
|
||||
{
|
||||
gl_draw_point<Indexable, dimension>::apply(i, z);
|
||||
}
|
||||
};
|
||||
template <typename Segment>
|
||||
struct gl_draw_indexable<Segment, segment_tag>
|
||||
: gl_draw_segment<Segment, geometry::dimension<Segment>::value>
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@ struct print_corner<Box, Corner, 1>
|
||||
template <typename Indexable, typename Tag>
|
||||
struct print_indexable
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG((false), NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag));
|
||||
};
|
||||
|
||||
template <typename Indexable>
|
||||
@@ -96,6 +97,21 @@ struct print_indexable<Indexable, point_tag>
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Indexable>
|
||||
struct print_indexable<Indexable, segment_tag>
|
||||
{
|
||||
static const size_t dimension = geometry::dimension<Indexable>::value;
|
||||
|
||||
static inline void apply(std::ostream &os, Indexable const& i)
|
||||
{
|
||||
os << '(';
|
||||
print_corner<Indexable, 0, dimension>::apply(os, i);
|
||||
os << ")-(";
|
||||
print_corner<Indexable, 1, dimension>::apply(os, i);
|
||||
os << ')';
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
|
||||
template <typename Indexable> inline
|
||||
|
||||
@@ -662,28 +662,11 @@ struct read_wkt<segment_tag, Segment>
|
||||
/*!
|
||||
\brief Parses OGC Well-Known Text (\ref WKT) into a geometry (any geometry)
|
||||
\ingroup wkt
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param wkt string containing \ref WKT
|
||||
\param geometry output geometry
|
||||
\par Example:
|
||||
\note It is case insensitive and can have the WKT forms "point", "point m", "point z", "point zm", "point mz"
|
||||
\note Empty sequences can have forms as "LINESTRING ()" or "POLYGON(())"
|
||||
Small example showing how to use read_wkt to build a point
|
||||
\dontinclude doxygen_1.cpp
|
||||
\skip example_from_wkt_point
|
||||
\line {
|
||||
\until }
|
||||
\par Example:
|
||||
Small example showing how to use read_wkt to build a linestring
|
||||
\dontinclude doxygen_1.cpp
|
||||
\skip example_from_wkt_linestring
|
||||
\line {
|
||||
\until }
|
||||
\par Example:
|
||||
Small example showing how to use read_wkt to build a polygon
|
||||
\dontinclude doxygen_1.cpp
|
||||
\skip example_from_wkt_polygon
|
||||
\line {
|
||||
\until }
|
||||
\param geometry \param_geometry output geometry
|
||||
\ingroup wkt
|
||||
\qbk{[include reference/io/read_wkt.qbk]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline void read_wkt(std::string const& wkt, Geometry& geometry)
|
||||
|
||||
@@ -22,10 +22,8 @@
|
||||
// Don't use namespace boost::geometry, to enable the library to stream custom
|
||||
// geometries which are living outside the namespace boost::geometry
|
||||
|
||||
/*!
|
||||
\brief Streams a geometry as Well-Known Text
|
||||
\ingroup wkt
|
||||
*/
|
||||
// This is currently not documented on purpose: the Doxygen 2 QBK generator
|
||||
// should be updated w.r.t. << which in the end ruins the DocBook XML
|
||||
template<typename Char, typename Traits, typename Geometry>
|
||||
inline std::basic_ostream<Char, Traits>& operator<<
|
||||
(
|
||||
|
||||
@@ -416,13 +416,10 @@ private:
|
||||
|
||||
/*!
|
||||
\brief Main WKT-streaming function
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
\ingroup wkt
|
||||
\par Example:
|
||||
Small example showing how to use the wkt helper function
|
||||
\dontinclude doxygen_1.cpp
|
||||
\skip example_as_wkt_vector
|
||||
\line {
|
||||
\until }
|
||||
\qbk{[include reference/io/wkt.qbk]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline wkt_manipulator<Geometry> wkt(Geometry const& geometry)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Boost.Geometry Index
|
||||
// Additional tests
|
||||
// OpenGL visualization
|
||||
|
||||
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2011-2014 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
|
||||
@@ -26,29 +26,172 @@
|
||||
#include <boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp>
|
||||
#include <boost/geometry/index/detail/rtree/utilities/statistics.hpp>
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
#define ENABLE_POINTS_AND_SEGMENTS
|
||||
|
||||
namespace bg = boost::geometry;
|
||||
namespace bgi = bg::index;
|
||||
|
||||
// used types
|
||||
|
||||
typedef bg::model::point<float, 2, boost::geometry::cs::cartesian> P;
|
||||
typedef bg::model::box<P> B;
|
||||
//bgi::rtree<B> t(2, 1);
|
||||
typedef bg::model::linestring<P> LS;
|
||||
typedef bg::model::segment<P> S;
|
||||
typedef bg::model::ring<P> R;
|
||||
typedef bg::model::polygon<P> Poly;
|
||||
typedef bg::model::multi_polygon<Poly> MPoly;
|
||||
|
||||
typedef bgi::rtree<
|
||||
B,
|
||||
bgi::rstar<4, 2>
|
||||
> RTree;
|
||||
RTree t;
|
||||
std::vector<B> vect;
|
||||
// containers variant
|
||||
|
||||
template <typename V>
|
||||
struct containers
|
||||
{
|
||||
containers & operator=(containers const& c)
|
||||
{
|
||||
tree = c.tree;
|
||||
values = c.values;
|
||||
result = c.result;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bgi::rtree< V, bgi::rstar<4, 2> > tree;
|
||||
std::vector<V> values;
|
||||
std::vector<V> result;
|
||||
};
|
||||
|
||||
boost::variant<
|
||||
containers<B>
|
||||
#ifdef ENABLE_POINTS_AND_SEGMENTS
|
||||
, containers<P>
|
||||
, containers<S>
|
||||
#endif
|
||||
> cont;
|
||||
|
||||
// visitors
|
||||
|
||||
template <typename Pred>
|
||||
struct query_v : boost::static_visitor<size_t>
|
||||
{
|
||||
Pred m_pred;
|
||||
query_v(Pred const& pred) : m_pred(pred) {}
|
||||
|
||||
template <typename C>
|
||||
size_t operator()(C & c) const
|
||||
{
|
||||
c.result.clear();
|
||||
return c.tree.query(m_pred, std::back_inserter(c.result));
|
||||
}
|
||||
};
|
||||
template <typename Cont, typename Pred>
|
||||
inline size_t query(Cont & cont, Pred const& pred)
|
||||
{
|
||||
return boost::apply_visitor(query_v<Pred>(pred), cont);
|
||||
}
|
||||
|
||||
struct print_result_v : boost::static_visitor<>
|
||||
{
|
||||
template <typename C>
|
||||
void operator()(C & c) const
|
||||
{
|
||||
for ( size_t i = 0 ; i < c.result.size() ; ++i )
|
||||
{
|
||||
bgi::detail::utilities::print_indexable(std::cout, c.result[i]);
|
||||
std::cout << '\n';
|
||||
}
|
||||
}
|
||||
};
|
||||
template <typename Cont>
|
||||
inline void print_result(Cont const& cont)
|
||||
{
|
||||
boost::apply_visitor(print_result_v(), cont);
|
||||
}
|
||||
|
||||
struct bounds_v : boost::static_visitor<B>
|
||||
{
|
||||
template <typename C>
|
||||
B operator()(C & c) const
|
||||
{
|
||||
return c.tree.bounds();
|
||||
}
|
||||
};
|
||||
template <typename Cont>
|
||||
inline B bounds(Cont const& cont)
|
||||
{
|
||||
return boost::apply_visitor(bounds_v(), cont);
|
||||
}
|
||||
|
||||
struct depth_v : boost::static_visitor<size_t>
|
||||
{
|
||||
template <typename C>
|
||||
size_t operator()(C & c) const
|
||||
{
|
||||
return get(c.tree);
|
||||
}
|
||||
template <typename RTree>
|
||||
static size_t get(RTree const& t)
|
||||
{
|
||||
return bgi::detail::rtree::utilities::view<RTree>(t).depth();
|
||||
}
|
||||
};
|
||||
template <typename Cont>
|
||||
inline size_t depth(Cont const& cont)
|
||||
{
|
||||
return boost::apply_visitor(depth_v(), cont);
|
||||
}
|
||||
|
||||
struct draw_tree_v : boost::static_visitor<>
|
||||
{
|
||||
template <typename C>
|
||||
void operator()(C & c) const
|
||||
{
|
||||
bgi::detail::rtree::utilities::gl_draw(c.tree);
|
||||
}
|
||||
};
|
||||
template <typename Cont>
|
||||
inline void draw_tree(Cont const& cont)
|
||||
{
|
||||
return boost::apply_visitor(draw_tree_v(), cont);
|
||||
}
|
||||
|
||||
struct draw_result_v : boost::static_visitor<>
|
||||
{
|
||||
template <typename C>
|
||||
void operator()(C & c) const
|
||||
{
|
||||
for ( size_t i = 0 ; i < c.result.size() ; ++i )
|
||||
{
|
||||
bgi::detail::utilities::gl_draw_indexable(c.result[i], depth_v::get(c.tree));
|
||||
}
|
||||
}
|
||||
};
|
||||
template <typename Cont>
|
||||
inline void draw_result(Cont const& cont)
|
||||
{
|
||||
return boost::apply_visitor(draw_result_v(), cont);
|
||||
}
|
||||
|
||||
struct print_tree_v : boost::static_visitor<>
|
||||
{
|
||||
template <typename C>
|
||||
void operator()(C & c) const
|
||||
{
|
||||
bgi::detail::rtree::utilities::print(std::cout, c.tree);
|
||||
}
|
||||
};
|
||||
template <typename Cont>
|
||||
inline void print_tree(Cont const& cont)
|
||||
{
|
||||
return boost::apply_visitor(print_tree_v(), cont);
|
||||
}
|
||||
|
||||
// globals used in querying
|
||||
|
||||
size_t found_count = 0;
|
||||
P search_point;
|
||||
size_t count = 5;
|
||||
std::vector<B> nearest_boxes;
|
||||
|
||||
P search_point;
|
||||
B search_box;
|
||||
R search_ring;
|
||||
Poly search_poly;
|
||||
@@ -58,38 +201,73 @@ LS search_linestring;
|
||||
LS search_path;
|
||||
|
||||
enum query_mode_type {
|
||||
qm_knn, qm_c, qm_d, qm_i, qm_o, qm_w, qm_nc, qm_nd, qm_ni, qm_no, qm_nw, qm_all, qm_ri, qm_pi, qm_mpi, qm_si, qm_lsi, qm_path
|
||||
qm_knn, qm_knnb, qm_knns, qm_c, qm_d, qm_i, qm_o, qm_w, qm_nc, qm_nd, qm_ni, qm_no, qm_nw, qm_all, qm_ri, qm_pi, qm_mpi, qm_si, qm_lsi, qm_path
|
||||
} query_mode = qm_knn;
|
||||
|
||||
bool search_valid = false;
|
||||
|
||||
// various queries
|
||||
|
||||
void query_knn()
|
||||
{
|
||||
float x = ( rand() % 1000 ) / 10.0f;
|
||||
float y = ( rand() % 1000 ) / 10.0f;
|
||||
|
||||
search_point = P(x, y);
|
||||
nearest_boxes.clear();
|
||||
found_count = t.query(
|
||||
bgi::nearest(search_point, count),
|
||||
std::back_inserter(nearest_boxes)
|
||||
);
|
||||
if ( query_mode == qm_knn )
|
||||
{
|
||||
search_point = P(x, y);
|
||||
found_count = query(cont, bgi::nearest(search_point, count));
|
||||
}
|
||||
else if ( query_mode == qm_knnb )
|
||||
{
|
||||
float w = 2 + ( rand() % 1000 ) / 500.0f;
|
||||
float h = 2 + ( rand() % 1000 ) / 500.0f;
|
||||
search_box = B(P(x - w, y - h), P(x + w, y + h));
|
||||
found_count = query(cont, bgi::nearest(search_box, count));
|
||||
}
|
||||
else if ( query_mode == qm_knns )
|
||||
{
|
||||
int signx = rand() % 2 ? 1 : -1;
|
||||
int signy = rand() % 2 ? 1 : -1;
|
||||
float w = (10 + ( rand() % 1000 ) / 100.0f) * signx;
|
||||
float h = (10 + ( rand() % 1000 ) / 100.0f) * signy;
|
||||
search_segment = S(P(x - w, y - h), P(x + w, y + h));
|
||||
found_count = query(cont, bgi::nearest(search_segment, count));
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
}
|
||||
|
||||
if ( found_count > 0 )
|
||||
{
|
||||
std::cout << "search point: ";
|
||||
bgi::detail::utilities::print_indexable(std::cout, search_point);
|
||||
std::cout << "\nfound: ";
|
||||
for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i )
|
||||
if ( query_mode == qm_knn )
|
||||
{
|
||||
bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]);
|
||||
std::cout << '\n';
|
||||
std::cout << "search point: ";
|
||||
bgi::detail::utilities::print_indexable(std::cout, search_point);
|
||||
}
|
||||
else if ( query_mode == qm_knnb )
|
||||
{
|
||||
std::cout << "search box: ";
|
||||
bgi::detail::utilities::print_indexable(std::cout, search_box);
|
||||
}
|
||||
else if ( query_mode == qm_knns )
|
||||
{
|
||||
std::cout << "search segment: ";
|
||||
bgi::detail::utilities::print_indexable(std::cout, search_segment);
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
}
|
||||
std::cout << "\nfound: ";
|
||||
print_result(cont);
|
||||
}
|
||||
else
|
||||
std::cout << "nearest not found\n";
|
||||
}
|
||||
|
||||
#ifndef ENABLE_POINTS_AND_SEGMENTS
|
||||
void query_path()
|
||||
{
|
||||
float x = ( rand() % 1000 ) / 10.0f;
|
||||
@@ -105,11 +283,7 @@ void query_path()
|
||||
search_path[2 * i + 1] = P(x+w, yy);
|
||||
}
|
||||
|
||||
nearest_boxes.clear();
|
||||
found_count = t.query(
|
||||
bgi::detail::path<LS>(search_path, count),
|
||||
std::back_inserter(nearest_boxes)
|
||||
);
|
||||
found_count = query(cont, bgi::detail::path<LS>(search_path, count));
|
||||
|
||||
if ( found_count > 0 )
|
||||
{
|
||||
@@ -117,15 +291,12 @@ void query_path()
|
||||
BOOST_FOREACH(P const& p, search_path)
|
||||
bgi::detail::utilities::print_indexable(std::cout, p);
|
||||
std::cout << "\nfound: ";
|
||||
for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i )
|
||||
{
|
||||
bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]);
|
||||
std::cout << '\n';
|
||||
}
|
||||
print_result(cont);
|
||||
}
|
||||
else
|
||||
std::cout << "values on path not found\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename Predicate>
|
||||
void query()
|
||||
@@ -138,26 +309,20 @@ void query()
|
||||
float h = 10 + ( rand() % 1000 ) / 100.0f;
|
||||
|
||||
search_box = B(P(x - w, y - h), P(x + w, y + h));
|
||||
nearest_boxes.clear();
|
||||
found_count = t.query(Predicate(search_box), std::back_inserter(nearest_boxes) );
|
||||
}
|
||||
else
|
||||
{
|
||||
search_box = t.bounds();
|
||||
nearest_boxes.clear();
|
||||
found_count = t.query(Predicate(search_box), std::back_inserter(nearest_boxes) );
|
||||
search_box = bounds(cont);
|
||||
}
|
||||
|
||||
found_count = query(cont, Predicate(search_box));
|
||||
|
||||
if ( found_count > 0 )
|
||||
{
|
||||
std::cout << "search box: ";
|
||||
bgi::detail::utilities::print_indexable(std::cout, search_box);
|
||||
std::cout << "\nfound: ";
|
||||
for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i )
|
||||
{
|
||||
bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]);
|
||||
std::cout << '\n';
|
||||
}
|
||||
print_result(cont);
|
||||
}
|
||||
else
|
||||
std::cout << "boxes not found\n";
|
||||
@@ -190,8 +355,7 @@ void query_ring()
|
||||
search_ring.push_back(P(x - w, y - h/2));
|
||||
search_ring.push_back(P(x - w, y - h));
|
||||
|
||||
nearest_boxes.clear();
|
||||
found_count = t.query(Predicate(search_ring), std::back_inserter(nearest_boxes) );
|
||||
found_count = query(cont, Predicate(search_ring));
|
||||
|
||||
if ( found_count > 0 )
|
||||
{
|
||||
@@ -202,11 +366,7 @@ void query_ring()
|
||||
std::cout << ' ';
|
||||
}
|
||||
std::cout << "\nfound: ";
|
||||
for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i )
|
||||
{
|
||||
bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]);
|
||||
std::cout << '\n';
|
||||
}
|
||||
print_result(cont);
|
||||
}
|
||||
else
|
||||
std::cout << "boxes not found\n";
|
||||
@@ -246,8 +406,7 @@ void query_poly()
|
||||
search_poly.inners()[0].push_back(P(x - w/2, y + h/2));
|
||||
search_poly.inners()[0].push_back(P(x - w/2, y - h/2));
|
||||
|
||||
nearest_boxes.clear();
|
||||
found_count = t.query(Predicate(search_poly), std::back_inserter(nearest_boxes) );
|
||||
found_count = query(cont, Predicate(search_poly));
|
||||
|
||||
if ( found_count > 0 )
|
||||
{
|
||||
@@ -258,11 +417,7 @@ void query_poly()
|
||||
std::cout << ' ';
|
||||
}
|
||||
std::cout << "\nfound: ";
|
||||
for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i )
|
||||
{
|
||||
bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]);
|
||||
std::cout << '\n';
|
||||
}
|
||||
print_result(cont);
|
||||
}
|
||||
else
|
||||
std::cout << "boxes not found\n";
|
||||
@@ -318,9 +473,8 @@ void query_multi_poly()
|
||||
search_multi_poly[2].outer().push_back(P(x + 6*w/5, y + 2*h));
|
||||
search_multi_poly[2].outer().push_back(P(x + 6*w/5, y + 6*h/5));
|
||||
|
||||
nearest_boxes.clear();
|
||||
found_count = t.query(Predicate(search_multi_poly), std::back_inserter(nearest_boxes) );
|
||||
|
||||
found_count = query(cont, Predicate(search_multi_poly));
|
||||
|
||||
if ( found_count > 0 )
|
||||
{
|
||||
std::cout << "search multi_poly[0] outer: ";
|
||||
@@ -330,11 +484,7 @@ void query_multi_poly()
|
||||
std::cout << ' ';
|
||||
}
|
||||
std::cout << "\nfound: ";
|
||||
for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i )
|
||||
{
|
||||
bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]);
|
||||
std::cout << '\n';
|
||||
}
|
||||
print_result(cont);
|
||||
}
|
||||
else
|
||||
std::cout << "boxes not found\n";
|
||||
@@ -355,9 +505,8 @@ void query_segment()
|
||||
boost::geometry::set<1, 0>(search_segment, x + w);
|
||||
boost::geometry::set<1, 1>(search_segment, y + h);
|
||||
|
||||
nearest_boxes.clear();
|
||||
found_count = t.query(Predicate(search_segment), std::back_inserter(nearest_boxes) );
|
||||
|
||||
found_count = query(cont, Predicate(search_segment));
|
||||
|
||||
if ( found_count > 0 )
|
||||
{
|
||||
std::cout << "search segment: ";
|
||||
@@ -365,11 +514,7 @@ void query_segment()
|
||||
bgi::detail::utilities::print_indexable(std::cout, P(x+w, y+h));
|
||||
|
||||
std::cout << "\nfound: ";
|
||||
for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i )
|
||||
{
|
||||
bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]);
|
||||
std::cout << '\n';
|
||||
}
|
||||
print_result(cont);
|
||||
}
|
||||
else
|
||||
std::cout << "boxes not found\n";
|
||||
@@ -393,9 +538,8 @@ void query_linestring()
|
||||
search_linestring.push_back(P(xx, yy));
|
||||
}
|
||||
|
||||
nearest_boxes.clear();
|
||||
found_count = t.query(Predicate(search_linestring), std::back_inserter(nearest_boxes) );
|
||||
|
||||
found_count = query(cont, Predicate(search_linestring));
|
||||
|
||||
if ( found_count > 0 )
|
||||
{
|
||||
std::cout << "search linestring: ";
|
||||
@@ -405,44 +549,46 @@ void query_linestring()
|
||||
std::cout << ' ';
|
||||
}
|
||||
std::cout << "\nfound: ";
|
||||
for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i )
|
||||
{
|
||||
bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]);
|
||||
std::cout << '\n';
|
||||
}
|
||||
print_result(cont);
|
||||
}
|
||||
else
|
||||
std::cout << "boxes not found\n";
|
||||
}
|
||||
|
||||
// the function running the correct query based on the query_mode
|
||||
|
||||
void search()
|
||||
{
|
||||
namespace d = bgi::detail;
|
||||
|
||||
if ( query_mode == qm_knn )
|
||||
if ( query_mode == qm_knn || query_mode == qm_knnb || query_mode == qm_knns )
|
||||
query_knn();
|
||||
else if ( query_mode == qm_c )
|
||||
query< d::spatial_predicate<B, d::covered_by_tag, false> >();
|
||||
else if ( query_mode == qm_d )
|
||||
query< d::spatial_predicate<B, d::disjoint_tag, false> >();
|
||||
else if ( query_mode == qm_i )
|
||||
query< d::spatial_predicate<B, d::intersects_tag, false> >();
|
||||
else if ( query_mode == qm_nd )
|
||||
query< d::spatial_predicate<B, d::disjoint_tag, true> >();
|
||||
else if ( query_mode == qm_ni )
|
||||
query< d::spatial_predicate<B, d::intersects_tag, true> >();
|
||||
else if ( query_mode == qm_all )
|
||||
query< d::spatial_predicate<B, d::intersects_tag, false> >();
|
||||
#ifdef ENABLE_POINTS_AND_SEGMENTS
|
||||
else
|
||||
std::cout << "query disabled\n";
|
||||
#else
|
||||
else if ( query_mode == qm_c )
|
||||
query< d::spatial_predicate<B, d::covered_by_tag, false> >();
|
||||
else if ( query_mode == qm_o )
|
||||
query< d::spatial_predicate<B, d::overlaps_tag, false> >();
|
||||
else if ( query_mode == qm_w )
|
||||
query< d::spatial_predicate<B, d::within_tag, false> >();
|
||||
else if ( query_mode == qm_nc )
|
||||
query< d::spatial_predicate<B, d::covered_by_tag, true> >();
|
||||
else if ( query_mode == qm_nd )
|
||||
query< d::spatial_predicate<B, d::disjoint_tag, true> >();
|
||||
else if ( query_mode == qm_ni )
|
||||
query< d::spatial_predicate<B, d::intersects_tag, true> >();
|
||||
else if ( query_mode == qm_no )
|
||||
query< d::spatial_predicate<B, d::overlaps_tag, true> >();
|
||||
else if ( query_mode == qm_nw )
|
||||
query< d::spatial_predicate<B, d::within_tag, true> >();
|
||||
else if ( query_mode == qm_all )
|
||||
query< d::spatial_predicate<B, d::intersects_tag, false> >();
|
||||
else if ( query_mode == qm_ri )
|
||||
query_ring< d::spatial_predicate<R, d::intersects_tag, false> >();
|
||||
else if ( query_mode == qm_pi )
|
||||
@@ -455,22 +601,34 @@ void search()
|
||||
query_linestring< d::spatial_predicate<LS, d::intersects_tag, false> >();
|
||||
else if ( query_mode == qm_path )
|
||||
query_path();
|
||||
#endif
|
||||
|
||||
search_valid = true;
|
||||
}
|
||||
|
||||
// various drawing functions
|
||||
|
||||
void draw_point(P const& p)
|
||||
{
|
||||
float x = boost::geometry::get<0>(p);
|
||||
float y = boost::geometry::get<1>(p);
|
||||
float z = depth(cont);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glVertex3f(x+1, y, z);
|
||||
glVertex3f(x, y+1, z);
|
||||
glVertex3f(x-1, y, z);
|
||||
glVertex3f(x, y-1, z);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void draw_knn_area(float min_distance, float max_distance)
|
||||
{
|
||||
float x = boost::geometry::get<0>(search_point);
|
||||
float y = boost::geometry::get<1>(search_point);
|
||||
float z = bgi::detail::rtree::utilities::view<RTree>(t).depth();
|
||||
float z = depth(cont);
|
||||
|
||||
// search point
|
||||
glBegin(GL_TRIANGLES);
|
||||
glVertex3f(x, y, z);
|
||||
glVertex3f(x + 1, y, z);
|
||||
glVertex3f(x + 1, y + 1, z);
|
||||
glEnd();
|
||||
draw_point(search_point);
|
||||
|
||||
// search min circle
|
||||
|
||||
@@ -495,7 +653,7 @@ void draw_linestring(LS const& ls)
|
||||
{
|
||||
float x = boost::geometry::get<0>(p);
|
||||
float y = boost::geometry::get<1>(p);
|
||||
float z = bgi::detail::rtree::utilities::view<RTree>(t).depth();
|
||||
float z = depth(cont);
|
||||
glVertex3f(x, y, z);
|
||||
}
|
||||
|
||||
@@ -508,7 +666,7 @@ void draw_segment(S const& s)
|
||||
float y1 = boost::geometry::get<0, 1>(s);
|
||||
float x2 = boost::geometry::get<1, 0>(s);
|
||||
float y2 = boost::geometry::get<1, 1>(s);
|
||||
float z = bgi::detail::rtree::utilities::view<RTree>(t).depth();
|
||||
float z = depth(cont);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex3f(x1, y1, z);
|
||||
@@ -523,7 +681,7 @@ void draw_box(Box const& box)
|
||||
float y1 = boost::geometry::get<bg::min_corner, 1>(box);
|
||||
float x2 = boost::geometry::get<bg::max_corner, 0>(box);
|
||||
float y2 = boost::geometry::get<bg::max_corner, 1>(box);
|
||||
float z = bgi::detail::rtree::utilities::view<RTree>(t).depth();
|
||||
float z = depth(cont);
|
||||
|
||||
// search box
|
||||
glBegin(GL_LINE_LOOP);
|
||||
@@ -537,7 +695,7 @@ void draw_box(Box const& box)
|
||||
template <typename Range>
|
||||
void draw_ring(Range const& range)
|
||||
{
|
||||
float z = bgi::detail::rtree::utilities::view<RTree>(t).depth();
|
||||
float z = depth(cont);
|
||||
|
||||
// search box
|
||||
glBegin(GL_LINE_LOOP);
|
||||
@@ -567,18 +725,24 @@ void draw_multi_polygon(MultiPolygon const& multi_polygon)
|
||||
draw_polygon(p);
|
||||
}
|
||||
|
||||
// render the scene -> tree, if searching data available also the query geometry and result
|
||||
|
||||
void render_scene(void)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
bgi::detail::rtree::utilities::gl_draw(t);
|
||||
draw_tree(cont);
|
||||
|
||||
if ( search_valid )
|
||||
{
|
||||
glColor3f(1.0f, 0.5f, 0.0f);
|
||||
glColor3f(1.0f, 0.25f, 0.0f);
|
||||
|
||||
if ( query_mode == qm_knn )
|
||||
draw_knn_area(0, 0);
|
||||
else if ( query_mode == qm_knnb )
|
||||
draw_box(search_box);
|
||||
else if ( query_mode == qm_knns )
|
||||
draw_segment(search_segment);
|
||||
else if ( query_mode == qm_ri )
|
||||
draw_ring(search_ring);
|
||||
else if ( query_mode == qm_pi )
|
||||
@@ -594,10 +758,9 @@ void render_scene(void)
|
||||
else
|
||||
draw_box(search_box);
|
||||
|
||||
for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i )
|
||||
bgi::detail::utilities::gl_draw_indexable(
|
||||
nearest_boxes[i],
|
||||
bgi::detail::rtree::utilities::view<RTree>(t).depth());
|
||||
glColor3f(1.0f, 0.5f, 0.0f);
|
||||
|
||||
draw_result(cont);
|
||||
}
|
||||
|
||||
glFlush();
|
||||
@@ -634,49 +797,100 @@ void resize(int w, int h)
|
||||
srand(1);
|
||||
}
|
||||
|
||||
// randomize various indexables
|
||||
|
||||
inline void rand_val(B & b)
|
||||
{
|
||||
float x = ( rand() % 100 );
|
||||
float y = ( rand() % 100 );
|
||||
float w = ( rand() % 2 ) + 1;
|
||||
float h = ( rand() % 2 ) + 1;
|
||||
b = B(P(x - w, y - h),P(x + w, y + h));
|
||||
}
|
||||
inline void rand_val(P & p)
|
||||
{
|
||||
float x = ( rand() % 100 );
|
||||
float y = ( rand() % 100 );
|
||||
p = P(x, y);
|
||||
}
|
||||
inline void rand_val(S & s)
|
||||
{
|
||||
float x = ( rand() % 100 );
|
||||
float y = ( rand() % 100 );
|
||||
float w = ( rand() % 2 + 1) * (rand() % 2 ? 1.0f : -1.0f);
|
||||
float h = ( rand() % 2 + 1) * (rand() % 2 ? 1.0f : -1.0f);
|
||||
s = S(P(x - w, y - h),P(x + w, y + h));
|
||||
}
|
||||
|
||||
// more higher-level visitors
|
||||
|
||||
struct insert_random_value_v : boost::static_visitor<>
|
||||
{
|
||||
template <typename V>
|
||||
void operator()(containers<V> & c) const
|
||||
{
|
||||
V v;
|
||||
rand_val(v);
|
||||
|
||||
boost::geometry::index::insert(c.tree, v);
|
||||
c.values.push_back(v);
|
||||
|
||||
std::cout << "inserted: ";
|
||||
bgi::detail::utilities::print_indexable(std::cout, v);
|
||||
std::cout << '\n';
|
||||
|
||||
std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(c.tree) ? "boxes OK\n" : "WRONG BOXES!\n" );
|
||||
std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(c.tree) ? "levels OK\n" : "WRONG LEVELS!\n" );
|
||||
std::cout << "\n";
|
||||
}
|
||||
};
|
||||
template <typename Cont>
|
||||
inline void insert_random_value(Cont & cont)
|
||||
{
|
||||
return boost::apply_visitor(insert_random_value_v(), cont);
|
||||
}
|
||||
|
||||
struct remove_random_value_v : boost::static_visitor<>
|
||||
{
|
||||
template <typename V>
|
||||
void operator()(containers<V> & c) const
|
||||
{
|
||||
if ( c.values.empty() )
|
||||
return;
|
||||
|
||||
size_t i = rand() % c.values.size();
|
||||
V v = c.values[i];
|
||||
|
||||
c.tree.remove(v);
|
||||
c.values.erase(c.values.begin() + i);
|
||||
|
||||
std::cout << "removed: ";
|
||||
bgi::detail::utilities::print_indexable(std::cout, v);
|
||||
std::cout << '\n';
|
||||
|
||||
std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(c.tree) ? "boxes OK\n" : "WRONG BOXES!\n" );
|
||||
std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(c.tree) ? "levels OK\n" : "WRONG LEVELS!\n" );
|
||||
std::cout << "\n";
|
||||
}
|
||||
};
|
||||
template <typename Cont>
|
||||
inline void remove_random_value(Cont & cont)
|
||||
{
|
||||
return boost::apply_visitor(remove_random_value_v(), cont);
|
||||
}
|
||||
|
||||
// handle mouse input
|
||||
|
||||
void mouse(int button, int state, int /*x*/, int /*y*/)
|
||||
{
|
||||
if ( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN )
|
||||
{
|
||||
float x = ( rand() % 100 );
|
||||
float y = ( rand() % 100 );
|
||||
float w = ( rand() % 2 ) + 1;
|
||||
float h = ( rand() % 2 ) + 1;
|
||||
|
||||
B b(P(x - w, y - h),P(x + w, y + h));
|
||||
|
||||
boost::geometry::index::insert(t, b);
|
||||
vect.push_back(b);
|
||||
|
||||
std::cout << "inserted: ";
|
||||
bgi::detail::utilities::print_indexable(std::cout, b);
|
||||
std::cout << '\n';
|
||||
|
||||
std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(t) ? "boxes OK\n" : "WRONG BOXES!\n" );
|
||||
std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(t) ? "levels OK\n" : "WRONG LEVELS!\n" );
|
||||
std::cout << "\n";
|
||||
|
||||
insert_random_value(cont);
|
||||
search_valid = false;
|
||||
}
|
||||
else if ( button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN )
|
||||
{
|
||||
if ( vect.empty() )
|
||||
return;
|
||||
|
||||
size_t i = rand() % vect.size();
|
||||
B b = vect[i];
|
||||
|
||||
bgi::remove(t, b);
|
||||
vect.erase(vect.begin() + i);
|
||||
|
||||
std::cout << "removed: ";
|
||||
bgi::detail::utilities::print_indexable(std::cout, b);
|
||||
std::cout << '\n';
|
||||
|
||||
std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(t) ? "boxes OK\n" : "WRONG BOXES!\n" );
|
||||
std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(t) ? "levels OK\n" : "WRONG LEVELS!\n" );
|
||||
std::cout << "\n";
|
||||
|
||||
remove_random_value(cont);
|
||||
search_valid = false;
|
||||
}
|
||||
else if ( button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN )
|
||||
@@ -687,71 +901,117 @@ void mouse(int button, int state, int /*x*/, int /*y*/)
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
// more higher-level visitors
|
||||
|
||||
struct insert_random_values_v : boost::static_visitor<>
|
||||
{
|
||||
template <typename V>
|
||||
void operator()(containers<V> & c) const
|
||||
{
|
||||
for ( size_t i = 0 ; i < 35 ; ++i )
|
||||
{
|
||||
V v;
|
||||
rand_val(v);
|
||||
|
||||
c.tree.insert(v);
|
||||
c.values.push_back(v);
|
||||
|
||||
std::cout << "inserted: ";
|
||||
bgi::detail::utilities::print_indexable(std::cout, v);
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(c.tree) ? "boxes OK\n" : "WRONG BOXES!\n" );
|
||||
std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(c.tree) ? "levels OK\n" : "WRONG LEVELS!\n" );
|
||||
std::cout << "\n";
|
||||
}
|
||||
};
|
||||
template <typename Cont>
|
||||
inline void insert_random_values(Cont & cont)
|
||||
{
|
||||
return boost::apply_visitor(insert_random_values_v(), cont);
|
||||
}
|
||||
|
||||
struct bulk_insert_random_values_v : boost::static_visitor<>
|
||||
{
|
||||
template <typename V>
|
||||
void operator()(containers<V> & c) const
|
||||
{
|
||||
c.values.clear();
|
||||
|
||||
for ( size_t i = 0 ; i < 35 ; ++i )
|
||||
{
|
||||
V v;
|
||||
rand_val(v);
|
||||
|
||||
c.values.push_back(v);
|
||||
|
||||
std::cout << "inserted: ";
|
||||
bgi::detail::utilities::print_indexable(std::cout, v);
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
create(c.tree, c.values);
|
||||
|
||||
std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(c.tree) ? "boxes OK\n" : "WRONG BOXES!\n" );
|
||||
std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(c.tree) ? "levels OK\n" : "WRONG LEVELS!\n" );
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
template <typename Tree, typename Values>
|
||||
void create(Tree & tree, Values const& values) const
|
||||
{
|
||||
Tree t(values);
|
||||
tree = boost::move(t);
|
||||
}
|
||||
};
|
||||
template <typename Cont>
|
||||
inline void bulk_insert_random_values(Cont & cont)
|
||||
{
|
||||
return boost::apply_visitor(bulk_insert_random_values_v(), cont);
|
||||
}
|
||||
|
||||
// handle keyboard input
|
||||
|
||||
std::string current_line;
|
||||
|
||||
void keyboard(unsigned char key, int /*x*/, int /*y*/)
|
||||
{
|
||||
if ( key == '\r' || key == '\n' )
|
||||
{
|
||||
if ( current_line == "t" )
|
||||
if ( current_line == "storeb" )
|
||||
{
|
||||
cont = containers<B>();
|
||||
glutPostRedisplay();
|
||||
}
|
||||
#ifdef ENABLE_POINTS_AND_SEGMENTS
|
||||
else if ( current_line == "storep" )
|
||||
{
|
||||
cont = containers<P>();
|
||||
glutPostRedisplay();
|
||||
}
|
||||
else if ( current_line == "stores" )
|
||||
{
|
||||
cont = containers<S>();
|
||||
glutPostRedisplay();
|
||||
}
|
||||
#endif
|
||||
else if ( current_line == "t" )
|
||||
{
|
||||
std::cout << "\n";
|
||||
bgi::detail::rtree::utilities::print(std::cout, t);
|
||||
print_tree(cont);
|
||||
std::cout << "\n";
|
||||
}
|
||||
else if ( current_line == "rand" )
|
||||
{
|
||||
for ( size_t i = 0 ; i < 35 ; ++i )
|
||||
{
|
||||
float x = ( rand() % 100 );
|
||||
float y = ( rand() % 100 );
|
||||
float w = ( rand() % 2 ) + 1;
|
||||
float h = ( rand() % 2 ) + 1;
|
||||
|
||||
B b(P(x - w, y - h),P(x + w, y + h));
|
||||
|
||||
boost::geometry::index::insert(t, b);
|
||||
vect.push_back(b);
|
||||
|
||||
std::cout << "inserted: ";
|
||||
bgi::detail::utilities::print_indexable(std::cout, b);
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(t) ? "boxes OK\n" : "WRONG BOXES!\n" );
|
||||
std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(t) ? "levels OK\n" : "WRONG LEVELS!\n" );
|
||||
std::cout << "\n";
|
||||
|
||||
insert_random_values(cont);
|
||||
search_valid = false;
|
||||
|
||||
glutPostRedisplay();
|
||||
}
|
||||
else if ( current_line == "bulk" )
|
||||
{
|
||||
vect.clear();
|
||||
|
||||
for ( size_t i = 0 ; i < 35 ; ++i )
|
||||
{
|
||||
float x = ( rand() % 100 );
|
||||
float y = ( rand() % 100 );
|
||||
float w = ( rand() % 2 ) + 1;
|
||||
float h = ( rand() % 2 ) + 1;
|
||||
|
||||
B b(P(x - w, y - h),P(x + w, y + h));
|
||||
vect.push_back(b);
|
||||
|
||||
std::cout << "inserted: ";
|
||||
bgi::detail::utilities::print_indexable(std::cout, b);
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
RTree t2(vect);
|
||||
t = boost::move(t2);
|
||||
|
||||
std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(t) ? "boxes OK\n" : "WRONG BOXES!\n" );
|
||||
std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(t) ? "levels OK\n" : "WRONG LEVELS!\n" );
|
||||
std::cout << "\n";
|
||||
|
||||
bulk_insert_random_values(cont);
|
||||
search_valid = false;
|
||||
|
||||
glutPostRedisplay();
|
||||
@@ -760,6 +1020,10 @@ void keyboard(unsigned char key, int /*x*/, int /*y*/)
|
||||
{
|
||||
if ( current_line == "knn" )
|
||||
query_mode = qm_knn;
|
||||
else if ( current_line == "knnb" )
|
||||
query_mode = qm_knnb;
|
||||
else if ( current_line == "knns" )
|
||||
query_mode = qm_knns;
|
||||
else if ( current_line == "c" )
|
||||
query_mode = qm_c;
|
||||
else if ( current_line == "d" )
|
||||
@@ -809,6 +1073,8 @@ void keyboard(unsigned char key, int /*x*/, int /*y*/)
|
||||
}
|
||||
}
|
||||
|
||||
// main function
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
glutInit(&argc, argv);
|
||||
|
||||
@@ -38,7 +38,7 @@ void check_geometry(Geometry const& geometry, std::string const& expected)
|
||||
}
|
||||
|
||||
template <typename Geometry, typename Points>
|
||||
void check_assign_points(Points const& points, std::string const& expected)
|
||||
void check_assign_points(Points const& points, std::string const& /*expected*/)
|
||||
{
|
||||
Geometry geometry;
|
||||
bg::assign_points(geometry, points);
|
||||
|
||||
@@ -226,6 +226,16 @@ void test_distance_segment_box(Strategy const& strategy)
|
||||
typedef test_distance_of_geometries<B, S> tester;
|
||||
typedef test_distance_of_geometries<B, IS> itester;
|
||||
|
||||
// 1st example by Adam Wulkiewicz
|
||||
tester::apply("BOX(5 51,42 96)",
|
||||
"SEGMENT(6.6799994 95.260002,35.119999 56.340004)",
|
||||
0, 0, strategy);
|
||||
|
||||
// 2nd example by Adam Wulkiewicz
|
||||
tester::apply("BOX(51 55,94 100)",
|
||||
"SEGMENT(92.439995 50.130001,59.959999 80.870003)",
|
||||
0, 0, strategy);
|
||||
|
||||
// segments that intersect the box
|
||||
tester::apply("box(0 0,1 1)",
|
||||
"segment(-1 0.5,0.5 0.75)",
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
template <typename Geometry, typename Hull>
|
||||
void check_convex_hull(Geometry const& geometry, Hull const& hull,
|
||||
std::size_t size_original, std::size_t size_hull,
|
||||
std::size_t /*size_original*/, std::size_t size_hull,
|
||||
double expected_area, bool reverse)
|
||||
{
|
||||
std::size_t n = bg::num_points(hull);
|
||||
|
||||
@@ -426,6 +426,146 @@ struct test_distance_of_geometries
|
||||
}
|
||||
};
|
||||
|
||||
//========================================================================
|
||||
|
||||
template <typename Box, typename Segment>
|
||||
struct test_distance_of_geometries
|
||||
<
|
||||
Box, Segment,
|
||||
94 /* box */, 92 /* segment */
|
||||
>
|
||||
{
|
||||
template
|
||||
<
|
||||
typename DistanceType,
|
||||
typename ComparableDistanceType,
|
||||
typename Strategy
|
||||
>
|
||||
static inline
|
||||
void apply(std::string const& wkt_box,
|
||||
std::string const& wkt_segment,
|
||||
DistanceType const& expected_distance,
|
||||
ComparableDistanceType const& expected_comparable_distance,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
test_distance_of_geometries
|
||||
<
|
||||
Segment, Box, 92, 94
|
||||
>::apply(wkt_segment,
|
||||
wkt_box,
|
||||
expected_distance,
|
||||
expected_comparable_distance,
|
||||
strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Segment, typename Box>
|
||||
struct test_distance_of_geometries
|
||||
<
|
||||
Segment, Box,
|
||||
92 /* segment */, 94 /* box */
|
||||
>
|
||||
: public test_distance_of_geometries<Segment, Box, 0, 0>
|
||||
{
|
||||
typedef test_distance_of_geometries<Segment, Box, 0, 0> base;
|
||||
|
||||
template
|
||||
<
|
||||
typename DistanceType,
|
||||
typename ComparableDistanceType,
|
||||
typename Strategy
|
||||
>
|
||||
static inline
|
||||
void apply(std::string const& wkt_segment,
|
||||
std::string const& wkt_box,
|
||||
DistanceType const& expected_distance,
|
||||
ComparableDistanceType const& expected_comparable_distance,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
Segment segment = from_wkt<Segment>(wkt_segment);
|
||||
Box box = from_wkt<Box>(wkt_box);
|
||||
apply(segment,
|
||||
box,
|
||||
expected_distance,
|
||||
expected_comparable_distance,
|
||||
strategy);
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename DistanceType,
|
||||
typename ComparableDistanceType,
|
||||
typename Strategy
|
||||
>
|
||||
static inline
|
||||
void apply(Segment const& segment,
|
||||
Box const& box,
|
||||
DistanceType const& expected_distance,
|
||||
ComparableDistanceType const& expected_comparable_distance,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename bg::strategy::distance::services::return_type
|
||||
<
|
||||
Strategy, Segment, Box
|
||||
>::type distance_result_type;
|
||||
|
||||
typedef typename bg::strategy::distance::services::comparable_type
|
||||
<
|
||||
Strategy
|
||||
>::type comparable_strategy;
|
||||
|
||||
typedef typename bg::strategy::distance::services::return_type
|
||||
<
|
||||
comparable_strategy, Segment, Box
|
||||
>::type comparable_distance_result_type;
|
||||
|
||||
|
||||
base::apply(segment, box, expected_distance,
|
||||
expected_comparable_distance, strategy);
|
||||
|
||||
comparable_strategy cstrategy =
|
||||
bg::strategy::distance::services::get_comparable
|
||||
<
|
||||
Strategy
|
||||
>::apply(strategy);
|
||||
|
||||
distance_result_type distance_generic =
|
||||
bg::detail::distance::segment_to_box_2D_generic
|
||||
<
|
||||
Segment, Box, Strategy
|
||||
>::apply(segment, box, strategy);
|
||||
|
||||
comparable_distance_result_type comparable_distance_generic =
|
||||
bg::detail::distance::segment_to_box_2D_generic
|
||||
<
|
||||
Segment, Box, comparable_strategy
|
||||
>::apply(segment, box, cstrategy);
|
||||
|
||||
|
||||
check_equal
|
||||
<
|
||||
distance_result_type
|
||||
>::apply(distance_generic, expected_distance);
|
||||
|
||||
check_equal
|
||||
<
|
||||
comparable_distance_result_type
|
||||
>::apply(comparable_distance_generic, expected_comparable_distance);
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << "... testing with naive seg-box distance algorithm..."
|
||||
<< std::endl;
|
||||
std::cout << "distance (generic algorithm) = "
|
||||
<< distance_generic << " ; "
|
||||
<< "comp. distance (generic algorithm) = "
|
||||
<< comparable_distance_generic
|
||||
<< std::endl;
|
||||
std::cout << std::endl << std::endl;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
//========================================================================
|
||||
|
||||
|
||||
@@ -36,8 +36,8 @@ struct check_result<Box, 2>
|
||||
ctype
|
||||
>::type type;
|
||||
|
||||
static void apply(Box const& b, const type& x1, const type& y1, const type& z1,
|
||||
const type& x2, const type& y2, const type& z2)
|
||||
static void apply(Box const& b, const type& x1, const type& y1, const type& /*z1*/,
|
||||
const type& x2, const type& y2, const type& /*z2*/)
|
||||
{
|
||||
BOOST_CHECK_CLOSE((bg::get<bg::min_corner, 0>(b)), x1, 0.001);
|
||||
BOOST_CHECK_CLOSE((bg::get<bg::min_corner, 1>(b)), y1, 0.001);
|
||||
|
||||
@@ -44,7 +44,9 @@ void test_geometry(std::string const& wkt, double expected_length)
|
||||
Geometry geometry;
|
||||
bg::read_wkt(wkt, geometry);
|
||||
test_length(geometry, expected_length);
|
||||
#if !defined(GEOMETRY_TEST_DEBUG)
|
||||
test_length(boost::variant<Geometry>(geometry), expected_length);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Geometry>
|
||||
|
||||
@@ -29,7 +29,7 @@ void test_perimeter(Geometry const& geometry, long double expected_perimeter)
|
||||
std::ostringstream out;
|
||||
out << typeid(typename bg::coordinate_type<Geometry>::type).name()
|
||||
<< std::endl
|
||||
<< typeid(typename bg::perimeter_result<Geometry>::type).name()
|
||||
<< typeid(typename bg::default_length_result<Geometry>::type).name()
|
||||
<< std::endl
|
||||
<< "perimeter : " << bg::perimeter(geometry)
|
||||
<< std::endl;
|
||||
@@ -48,7 +48,9 @@ void test_geometry(std::string const& wkt, double expected_perimeter)
|
||||
boost::variant<Geometry> v(geometry);
|
||||
|
||||
test_perimeter(geometry, expected_perimeter);
|
||||
#if !defined(GEOMETRY_TEST_DEBUG)
|
||||
test_perimeter(v, expected_perimeter);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Geometry>
|
||||
|
||||