[geometry][index]: implemented version of linear find_greatest_normalized_separation optimized for Points. Removed index::detail::traits, the official ones used instead.

[SVN r84840]
This commit is contained in:
Adam Wulkiewicz
2013-06-19 23:00:12 +00:00
parent efdcd29a8b
commit 45970c5696
19 changed files with 228 additions and 255 deletions

View File

@@ -42,8 +42,8 @@ struct sum_for_indexable_dimension<Point, BoxIndexable, box_tag, comparable_dist
inline static result_type apply(Point const& pt, BoxIndexable const& i)
{
typedef typename index::detail::traits::coordinate_type<Point>::type point_coord_t;
typedef typename index::detail::traits::coordinate_type<BoxIndexable>::type indexable_coord_t;
typedef typename coordinate_type<Point>::type point_coord_t;
typedef typename coordinate_type<BoxIndexable>::type indexable_coord_t;
point_coord_t pt_c = geometry::get<DimensionIndex>(pt);
indexable_coord_t ind_c_min = geometry::get<geometry::min_corner, DimensionIndex>(i);
@@ -65,9 +65,9 @@ comparable_distance_centroid(Point const& pt, Indexable const& i)
return detail::sum_for_indexable<
Point,
Indexable,
typename index::detail::traits::tag<Indexable>::type,
typename tag<Indexable>::type,
detail::comparable_distance_centroid_tag,
index::detail::traits::dimension<Indexable>::value
dimension<Indexable>::value
>::apply(pt, i);
}

View File

@@ -30,8 +30,8 @@ struct sum_for_indexable_dimension<Point, BoxIndexable, box_tag, comparable_dist
inline static result_type apply(Point const& pt, BoxIndexable const& i)
{
typedef typename index::detail::traits::coordinate_type<Point>::type point_coord_t;
typedef typename index::detail::traits::coordinate_type<BoxIndexable>::type indexable_coord_t;
typedef typename coordinate_type<Point>::type point_coord_t;
typedef typename coordinate_type<BoxIndexable>::type indexable_coord_t;
point_coord_t pt_c = geometry::get<DimensionIndex>(pt);
indexable_coord_t ind_c_min = geometry::get<geometry::min_corner, DimensionIndex>(i);
@@ -55,9 +55,9 @@ comparable_distance_far(Point const& pt, Indexable const& i)
return detail::sum_for_indexable<
Point,
Indexable,
typename index::detail::traits::tag<Indexable>::type,
typename tag<Indexable>::type,
detail::comparable_distance_far_tag,
index::detail::traits::dimension<Indexable>::value
dimension<Indexable>::value
>::apply(pt, i);
}

View File

@@ -41,8 +41,8 @@ struct sum_for_indexable_dimension<Point, BoxIndexable, box_tag, comparable_dist
inline static result_type apply(Point const& pt, BoxIndexable const& i)
{
typedef typename index::detail::traits::coordinate_type<Point>::type point_coord_t;
typedef typename index::detail::traits::coordinate_type<BoxIndexable>::type indexable_coord_t;
typedef typename coordinate_type<Point>::type point_coord_t;
typedef typename coordinate_type<BoxIndexable>::type indexable_coord_t;
point_coord_t pt_c = geometry::get<DimensionIndex>(pt);
indexable_coord_t ind_c_min = geometry::get<geometry::min_corner, DimensionIndex>(i);
@@ -66,9 +66,9 @@ comparable_distance_near(Point const& pt, Indexable const& i)
return detail::sum_for_indexable<
Point,
Indexable,
typename index::detail::traits::tag<Indexable>::type,
typename tag<Indexable>::type,
detail::comparable_distance_near_tag,
index::detail::traits::dimension<Indexable>::value
dimension<Indexable>::value
>::apply(pt, i);
}

View File

@@ -11,8 +11,6 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_CONTENT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_CONTENT_HPP
#include <boost/geometry/index/detail/indexable.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
template <typename Indexable>
@@ -35,7 +33,7 @@ struct content_box
static inline typename detail::default_content_result<Box>::type apply(Box const& b)
{
return content_box<Box, CurrentDimension - 1>::apply(b) *
( detail::get<max_corner, CurrentDimension - 1>(b) - detail::get<min_corner, CurrentDimension - 1>(b) );
( get<max_corner, CurrentDimension - 1>(b) - get<min_corner, CurrentDimension - 1>(b) );
}
};
@@ -44,7 +42,7 @@ struct content_box<Box, 1>
{
static inline typename detail::default_content_result<Box>::type apply(Box const& b)
{
return detail::get<max_corner, 0>(b) - detail::get<min_corner, 0>(b);
return get<max_corner, 0>(b) - get<min_corner, 0>(b);
}
};

View File

@@ -14,11 +14,26 @@
namespace boost { namespace geometry { namespace index { namespace detail {
template <typename T>
inline T diff_abs(T const& v1, T const& v2)
inline T diff_abs_dispatch(T const& v1, T const& v2, boost::mpl::bool_<true> const& /*is_integral*/)
{
return v1 < v2 ? v2 - v1 : v1 - v2;
}
template <typename T>
inline T diff_abs_dispatch(T const& v1, T const& v2, boost::mpl::bool_<false> const& /*is_integral*/)
{
return ::fabs(v1 - v2);
}
template <typename T>
inline T diff_abs(T const& v1, T const& v2)
{
typedef boost::mpl::bool_<
boost::is_integral<T>::value
> is_integral;
return diff_abs_dispatch(v1, v2, is_integral());
}
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_DIFF_ABS_HPP

View File

@@ -11,8 +11,6 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP
#include <boost/geometry/index/detail/indexable.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
namespace dispatch {
@@ -21,14 +19,14 @@ template <typename Box, size_t Dimension>
struct is_valid_box
{
BOOST_MPL_ASSERT_MSG(
(0 < Dimension && Dimension <= detail::traits::dimension<Box>::value),
(0 < Dimension && Dimension <= dimension<Box>::value),
INVALID_DIMENSION_PARAMETER,
(is_valid_box));
static inline bool apply(Box const& b)
{
return is_valid_box<Box, Dimension - 1>::apply(b) &&
( detail::get<min_corner, Dimension - 1>(b) <= detail::get<max_corner, Dimension - 1>(b) );
( get<min_corner, Dimension - 1>(b) <= get<max_corner, Dimension - 1>(b) );
}
};
@@ -37,7 +35,7 @@ struct is_valid_box<Box, 1>
{
static inline bool apply(Box const& b)
{
return detail::get<min_corner, 0>(b) <= detail::get<max_corner, 0>(b);
return get<min_corner, 0>(b) <= get<max_corner, 0>(b);
}
};
@@ -64,7 +62,7 @@ struct is_valid<Indexable, box_tag>
{
static inline bool apply(Indexable const& b)
{
return dispatch::is_valid_box<Indexable, detail::traits::dimension<Indexable>::value>::apply(b);
return dispatch::is_valid_box<Indexable, dimension<Indexable>::value>::apply(b);
}
};
@@ -73,7 +71,7 @@ struct is_valid<Indexable, box_tag>
template <typename Indexable>
inline bool is_valid(Indexable const& b)
{
return dispatch::is_valid<Indexable, typename detail::traits::tag<Indexable>::type>::apply(b);
return dispatch::is_valid<Indexable, typename tag<Indexable>::type>::apply(b);
}
}}}} // namespace boost::geometry::index::detail

View File

@@ -11,8 +11,6 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
#include <boost/geometry/index/detail/indexable.hpp>
// WARNING! comparable_margin() will work only if the same Geometries are compared
// so it shouldn't be used in the case of Variants!

View File

@@ -32,8 +32,8 @@ struct smallest_for_indexable_dimension<Point, BoxIndexable, box_tag, minmaxdist
inline static result_type apply(Point const& pt, BoxIndexable const& i, result_type const& maxd)
{
typedef typename index::traits::coordinate_type<Point>::type point_coord_t;
typedef typename index::traits::coordinate_type<BoxIndexable>::type indexable_coord_t;
typedef typename coordinate_type<Point>::type point_coord_t;
typedef typename coordinate_type<BoxIndexable>::type indexable_coord_t;
point_coord_t pt_c = geometry::get<DimensionIndex>(pt);
indexable_coord_t ind_c_min = geometry::get<geometry::min_corner, DimensionIndex>(i);
@@ -95,7 +95,7 @@ struct minmaxdist_impl<Point, Indexable, box_tag>
Indexable,
box_tag,
minmaxdist_tag,
index::traits::dimension<Indexable>::value
dimension<Indexable>::value
>::apply(pt, i, maxd);
}
};
@@ -110,7 +110,7 @@ minmaxdist(Point const& pt, Indexable const& i)
return detail::minmaxdist_impl<
Point,
Indexable,
typename index::traits::tag<Indexable>::type
typename tag<Indexable>::type
>::apply(pt, i);
}

View File

@@ -26,11 +26,11 @@ struct path_intersection
template <typename Indexable, typename Segment>
struct path_intersection<Indexable, Segment, box_tag, segment_tag>
{
typedef typename default_distance_result<typename ::boost::geometry::traits::point_type<Segment>::type>::type comparable_distance_type;
typedef typename default_distance_result<typename point_type<Segment>::type>::type comparable_distance_type;
static inline bool apply(Indexable const& b, Segment const& segment, comparable_distance_type & comparable_distance)
{
typedef typename ::boost::geometry::traits::point_type<Segment>::type point_type;
typedef typename point_type<Segment>::type point_type;
point_type p1, p2;
geometry::detail::assign_point_from_index<0>(segment, p1);
geometry::detail::assign_point_from_index<1>(segment, p2);
@@ -90,8 +90,8 @@ struct default_path_intersection_distance_type
{
typedef typename dispatch::path_intersection<
Indexable, SegmentOrLinestring,
typename detail::traits::tag<Indexable>::type,
typename detail::traits::tag<SegmentOrLinestring>::type
typename tag<Indexable>::type,
typename tag<SegmentOrLinestring>::type
>::comparable_distance_type type;
};
@@ -104,8 +104,8 @@ bool path_intersection(Indexable const& b,
return dispatch::path_intersection<
Indexable, SegmentOrLinestring,
typename detail::traits::tag<Indexable>::type,
typename detail::traits::tag<SegmentOrLinestring>::type
typename tag<Indexable>::type,
typename tag<SegmentOrLinestring>::type
>::apply(b, path, comparable_distance);
}

View File

@@ -11,8 +11,6 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SEGMENT_INTERSECTION_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SEGMENT_INTERSECTION_HPP
#include <boost/geometry/index/detail/indexable.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
//template <typename Indexable, typename Point>
@@ -20,8 +18,8 @@ namespace boost { namespace geometry { namespace index { namespace detail {
//{
// typedef typename select_most_precise<
// typename select_most_precise<
// typename traits::coordinate_type<Indexable>::type,
// typename traits::coordinate_type<Point>::type
// typename coordinate_type<Indexable>::type,
// typename coordinate_type<Point>::type
// >::type,
// float // TODO - use bigger type, calculated from the size of coordinate types
// >::type type;
@@ -36,9 +34,9 @@ namespace dispatch {
template <typename Box, typename Point, size_t I>
struct box_segment_intersection_dim
{
BOOST_STATIC_ASSERT(I < traits::dimension<Box>::value);
BOOST_STATIC_ASSERT(I < traits::dimension<Point>::value);
BOOST_STATIC_ASSERT(traits::dimension<Point>::value == traits::dimension<Box>::value);
BOOST_STATIC_ASSERT(I < dimension<Box>::value);
BOOST_STATIC_ASSERT(I < dimension<Point>::value);
BOOST_STATIC_ASSERT(dimension<Point>::value == dimension<Box>::value);
// WARNING! - RelativeDistance must be IEEE float for this to work
@@ -47,8 +45,8 @@ struct box_segment_intersection_dim
RelativeDistance & t_near, RelativeDistance & t_far)
{
RelativeDistance ray_d = geometry::get<I>(p1) - geometry::get<I>(p0);
RelativeDistance tn = ( detail::get<min_corner, I>(b) - geometry::get<I>(p0) ) / ray_d;
RelativeDistance tf = ( detail::get<max_corner, I>(b) - geometry::get<I>(p0) ) / ray_d;
RelativeDistance tn = ( geometry::get<min_corner, I>(b) - geometry::get<I>(p0) ) / ray_d;
RelativeDistance tf = ( geometry::get<max_corner, I>(b) - geometry::get<I>(p0) ) / ray_d;
if ( tf < tn )
::std::swap(tn, tf);
@@ -105,7 +103,7 @@ struct segment_intersection<Indexable, Point, point_tag>
template <typename Indexable, typename Point>
struct segment_intersection<Indexable, Point, box_tag>
{
typedef dispatch::box_segment_intersection<Indexable, Point, detail::traits::dimension<Indexable>::value> impl;
typedef dispatch::box_segment_intersection<Indexable, Point, dimension<Indexable>::value> impl;
template <typename RelativeDistance>
static inline bool apply(Indexable const& b, Point const& p0, Point const& p1, RelativeDistance & relative_distance)
@@ -134,7 +132,7 @@ bool segment_intersection(Indexable const& b,
return dispatch::segment_intersection<
Indexable, Point,
typename detail::traits::tag<Indexable>::type
typename tag<Indexable>::type
>::apply(b, p0, p1, relative_distance);
}

View File

@@ -11,8 +11,6 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SUM_FOR_INDEXABLE_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SUM_FOR_INDEXABLE_HPP
#include <boost/geometry/index/detail/indexable.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
template <

View File

@@ -1,139 +0,0 @@
// Boost.Geometry Index
//
// Indexable's traits and related functions
//
// 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_INDEXABLE_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_INDEXABLE_HPP
namespace boost { namespace geometry { namespace index { namespace detail {
namespace dispatch {
template <typename Indexable, typename IndexableTag>
struct point_type
{
typedef void type;
};
template <typename Indexable>
struct point_type<Indexable, geometry::box_tag>
{
typedef typename geometry::traits::point_type<Indexable>::type type;
};
template <typename Indexable>
struct point_type<Indexable, geometry::point_tag>
{
typedef Indexable type;
};
} // namespace dispatch
namespace traits {
template <typename Indexable>
struct point_type
{
typedef typename dispatch::point_type<
Indexable,
typename geometry::traits::tag<Indexable>::type
>::type type;
};
template <typename Indexable>
struct coordinate_system
{
typedef typename geometry::traits::coordinate_system<
typename point_type<Indexable>::type
>::type type;
};
template <typename Indexable>
struct coordinate_type
{
typedef typename geometry::traits::coordinate_type<
typename point_type<Indexable>::type
>::type type;
};
template <typename Indexable>
struct dimension
{
static const size_t value =
geometry::traits::dimension<
typename point_type<Indexable>::type
>::value;
};
template <typename Indexable>
struct tag
{
typedef typename geometry::traits::tag<
Indexable
>::type type;
};
} // namespace traits
namespace dispatch {
template <size_t Corner, size_t DimensionIndex, typename Indexable, typename IndexableTag>
struct indexable_indexed_access {};
template <size_t Corner, size_t DimensionIndex, typename Indexable>
struct indexable_indexed_access<Corner, DimensionIndex, Indexable, box_tag>
{
typedef typename traits::point_type<Indexable>::type point_type;
typedef typename traits::coordinate_type<point_type>::type coordinate_type;
static inline coordinate_type get(Indexable const& i)
{
return geometry::get<Corner, DimensionIndex>(i);
}
};
template <size_t Corner, size_t DimensionIndex, typename Indexable>
struct indexable_indexed_access<Corner, DimensionIndex, Indexable, point_tag>
{
typedef typename traits::coordinate_type<Indexable>::type coordinate_type;
static inline coordinate_type get(Indexable const& i)
{
return geometry::get<DimensionIndex>(i);
}
};
} // namespace dispatch
template <size_t Corner, size_t DimensionIndex, typename Indexable>
typename traits::coordinate_type<Indexable>::type get(Indexable const& i)
{
return dispatch::indexable_indexed_access<
Corner,
DimensionIndex,
Indexable,
typename geometry::traits::tag<Indexable>::type
>::get(i);
}
template <typename Indexable>
struct default_box_type
{
typedef geometry::model::box<
geometry::model::point<
typename traits::coordinate_type<Indexable>::type,
traits::dimension<Indexable>::value,
typename traits::coordinate_system<Indexable>::type
>
> type;
};
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_INDEX_DETAIL_INDEXABLE_HPP

View File

@@ -26,21 +26,49 @@ namespace detail { namespace rtree {
namespace linear {
template <typename R, typename T>
inline R difference_dispatch(T const& from, T const& to, ::boost::mpl::bool_<false> const& /*is_unsigned*/)
{
return to - from;
}
template <typename R, typename T>
inline R difference_dispatch(T const& from, T const& to, ::boost::mpl::bool_<true> const& /*is_unsigned*/)
{
return from <= to ? R(to - from) : -R(from - to);
}
template <typename R, typename T>
inline R difference(T const& from, T const& to)
{
BOOST_MPL_ASSERT_MSG(!boost::is_unsigned<R>::value, RESULT_CANT_BE_UNSIGNED, (R));
typedef ::boost::mpl::bool_<
boost::is_unsigned<T>::value
> is_unsigned;
return difference_dispatch<R>(from, to, is_unsigned());
}
// TODO: awulkiew - there are loops inside find_greatest_normalized_separation::apply()
// iteration is done for each DimensionIndex.
// Separations and seeds for all DimensionIndex(es) could be calculated at once, stored, then the greatest would be choosen.
// TODO: Implement separate version for Points
// The following struct/method was adapted for the preliminary version of the R-tree. Then it was called:
// void find_normalized_separations(std::vector<Box> const& boxes, T& separation, unsigned int& first, unsigned int& second) const
template <typename Elements, typename Parameters, typename Translator, size_t DimensionIndex>
template <typename Elements, typename Parameters, typename Translator, typename Tag, size_t DimensionIndex>
struct find_greatest_normalized_separation
{
BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag));
};
template <typename Elements, typename Parameters, typename Translator, size_t DimensionIndex>
struct find_greatest_normalized_separation<Elements, Parameters, Translator, box_tag, DimensionIndex>
{
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename index::detail::traits::coordinate_type<indexable_type>::type coordinate_type;
typedef typename coordinate_type<indexable_type>::type coordinate_type;
typedef typename boost::mpl::if_c<
boost::is_integral<coordinate_type>::value,
@@ -48,10 +76,6 @@ struct find_greatest_normalized_separation
coordinate_type
>::type separation_type;
typedef ::boost::mpl::bool_<
boost::is_unsigned<coordinate_type>::value
> is_coordinate_type_unsigned;
static inline void apply(Elements const& elements,
Parameters const& parameters,
Translator const& translator,
@@ -64,15 +88,15 @@ struct find_greatest_normalized_separation
BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements");
// find the lowest low, highest high
coordinate_type lowest_low = index::detail::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[0], translator));
coordinate_type highest_high = index::detail::get<max_corner, DimensionIndex>(rtree::element_indexable(elements[0], translator));
coordinate_type lowest_low = geometry::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[0], translator));
coordinate_type highest_high = geometry::get<max_corner, DimensionIndex>(rtree::element_indexable(elements[0], translator));
// and the lowest high
coordinate_type lowest_high = highest_high;
size_t lowest_high_index = 0;
for ( size_t i = 1 ; i < elements_count ; ++i )
{
coordinate_type min_coord = index::detail::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[i], translator));
coordinate_type max_coord = index::detail::get<max_corner, DimensionIndex>(rtree::element_indexable(elements[i], translator));
coordinate_type min_coord = geometry::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[i], translator));
coordinate_type max_coord = geometry::get<max_corner, DimensionIndex>(rtree::element_indexable(elements[i], translator));
if ( max_coord < lowest_high )
{
@@ -89,10 +113,10 @@ struct find_greatest_normalized_separation
// find the highest low
size_t highest_low_index = lowest_high_index == 0 ? 1 : 0;
coordinate_type highest_low = index::detail::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[highest_low_index], translator));
coordinate_type highest_low = geometry::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[highest_low_index], translator));
for ( size_t i = highest_low_index ; i < elements_count ; ++i )
{
coordinate_type min_coord = index::detail::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[i], translator));
coordinate_type min_coord = geometry::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[i], translator));
if ( highest_low < min_coord &&
i != lowest_high_index )
{
@@ -103,7 +127,8 @@ struct find_greatest_normalized_separation
coordinate_type const width = highest_high - lowest_low;
separation = difference(highest_low, lowest_high, is_coordinate_type_unsigned());
// highest_low - lowest_high
separation = difference<separation_type>(lowest_high, highest_low);
// BOOST_ASSERT(0 <= width);
if ( std::numeric_limits<coordinate_type>::epsilon() < width )
separation /= width;
@@ -113,21 +138,60 @@ struct find_greatest_normalized_separation
BOOST_GEOMETRY_INDEX_DETAIL_USE_PARAM(parameters)
}
};
static inline separation_type difference(coordinate_type const& highest_low,
coordinate_type const& lowest_high,
::boost::mpl::bool_<false> const& /*is_unsigned*/)
{
return (highest_low - lowest_high);
}
// Version for points doesn't calculate normalized separation since it would always be equal to 1
// It returns two seeds most distant to each other, separation is equal to distance
template <typename Elements, typename Parameters, typename Translator, size_t DimensionIndex>
struct find_greatest_normalized_separation<Elements, Parameters, Translator, point_tag, DimensionIndex>
{
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename coordinate_type<indexable_type>::type coordinate_type;
static inline separation_type difference(coordinate_type const& highest_low,
coordinate_type const& lowest_high,
::boost::mpl::bool_<true> const& /*is_unsigned*/)
typedef coordinate_type separation_type;
static inline void apply(Elements const& elements,
Parameters const& parameters,
Translator const& translator,
separation_type & separation,
size_t & seed1,
size_t & seed2)
{
return lowest_high <= highest_low ?
separation_type(highest_low - lowest_high) :
-separation_type(lowest_high - highest_low);
const size_t elements_count = parameters.get_max_elements() + 1;
BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "unexpected number of elements");
BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements");
// find the lowest low, highest high
coordinate_type lowest = geometry::get<DimensionIndex>(rtree::element_indexable(elements[0], translator));
coordinate_type highest = geometry::get<DimensionIndex>(rtree::element_indexable(elements[0], translator));
size_t lowest_index = 0;
size_t highest_index = 0;
for ( size_t i = 1 ; i < elements_count ; ++i )
{
coordinate_type coord = geometry::get<DimensionIndex>(rtree::element_indexable(elements[i], translator));
if ( coord < lowest )
{
lowest = coord;
lowest_index = i;
}
if ( highest < coord )
{
highest = coord;
highest_index = i;
}
}
separation = highest - lowest;
seed1 = lowest_index;
seed2 = highest_index;
if ( lowest_index == highest_index )
seed2 = (lowest_index + 1) % elements_count; // % is just in case since if this is true lowest_index is 0
BOOST_GEOMETRY_INDEX_DETAIL_USE_PARAM(parameters)
}
};
@@ -138,9 +202,13 @@ struct pick_seeds_impl
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename index::detail::traits::coordinate_type<indexable_type>::type coordinate_type;
typedef typename coordinate_type<indexable_type>::type coordinate_type;
typedef find_greatest_normalized_separation<
Elements, Parameters, Translator,
typename tag<indexable_type>::type, Dimension - 1
> find_norm_sep;
typedef find_greatest_normalized_separation<Elements, Parameters, Translator, Dimension - 1> find_norm_sep;
typedef typename find_norm_sep::separation_type separation_type;
static inline void apply(Elements const& elements,
@@ -171,9 +239,13 @@ struct pick_seeds_impl<Elements, Parameters, Translator, 1>
{
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename index::detail::traits::coordinate_type<indexable_type>::type coordinate_type;
typedef typename coordinate_type<indexable_type>::type coordinate_type;
typedef find_greatest_normalized_separation<
Elements, Parameters, Translator,
typename tag<indexable_type>::type, 0
> find_norm_sep;
typedef find_greatest_normalized_separation<Elements, Parameters, Translator, 0> find_norm_sep;
typedef typename find_norm_sep::separation_type separation_type;
static inline void apply(Elements const& elements,
@@ -194,9 +266,9 @@ struct pick_seeds
{
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename index::detail::traits::coordinate_type<indexable_type>::type coordinate_type;
typedef typename coordinate_type<indexable_type>::type coordinate_type;
static const size_t dimension = index::detail::traits::dimension<indexable_type>::value;
static const size_t dimension = dimension<indexable_type>::value;
typedef pick_seeds_impl<Elements, Parameters, Translator, dimension> impl;
typedef typename impl::separation_type separation_type;
@@ -237,7 +309,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear
typedef typename rtree::elements_type<Node>::type elements_type;
typedef typename elements_type::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename index::detail::traits::coordinate_type<indexable_type>::type coordinate_type;
typedef typename coordinate_type<indexable_type>::type coordinate_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
elements_type & elements1 = rtree::elements(n);

View File

@@ -31,7 +31,7 @@ struct pick_seeds
{
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename index::detail::traits::coordinate_type<indexable_type>::type coordinate_type;
typedef typename coordinate_type<indexable_type>::type coordinate_type;
typedef Box box_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
@@ -100,7 +100,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
typedef typename rtree::elements_type<Node>::type elements_type;
typedef typename elements_type::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename index::detail::traits::coordinate_type<indexable_type>::type coordinate_type;
typedef typename coordinate_type<indexable_type>::type coordinate_type;
elements_type & elements1 = rtree::elements(n);
elements_type & elements2 = rtree::elements(second_node);

View File

@@ -25,8 +25,14 @@ namespace detail { namespace rtree {
namespace rstar {
template <typename Element, typename Translator, size_t Corner, size_t AxisIndex>
template <typename Element, typename Translator, typename Tag, size_t Corner, size_t AxisIndex>
class element_axis_corner_less
{
BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag));
};
template <typename Element, typename Translator, size_t Corner, size_t AxisIndex>
class element_axis_corner_less<Element, Translator, box_tag, Corner, AxisIndex>
{
public:
element_axis_corner_less(Translator const& tr)
@@ -35,8 +41,26 @@ public:
bool operator()(Element const& e1, Element const& e2) const
{
return index::detail::get<Corner, AxisIndex>(rtree::element_indexable(e1, m_tr))
< index::detail::get<Corner, AxisIndex>(rtree::element_indexable(e2, m_tr));
return geometry::get<Corner, AxisIndex>(rtree::element_indexable(e1, m_tr))
< geometry::get<Corner, AxisIndex>(rtree::element_indexable(e2, m_tr));
}
private:
Translator const& m_tr;
};
template <typename Element, typename Translator, size_t Corner, size_t AxisIndex>
class element_axis_corner_less<Element, Translator, point_tag, Corner, AxisIndex>
{
public:
element_axis_corner_less(Translator const& tr)
: m_tr(tr)
{}
bool operator()(Element const& e1, Element const& e2) const
{
return geometry::get<AxisIndex>(rtree::element_indexable(e1, m_tr))
< geometry::get<AxisIndex>(rtree::element_indexable(e2, m_tr));
}
private:
@@ -59,6 +83,8 @@ struct choose_split_axis_and_index_for_corner
Translator const& translator)
{
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename tag<indexable_type>::type indexable_tag;
BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == parameters.get_max_elements() + 1, "wrong number of elements");
@@ -66,7 +92,7 @@ struct choose_split_axis_and_index_for_corner
Elements elements_copy(elements); // MAY THROW, STRONG (alloc, copy)
// sort elements
element_axis_corner_less<element_type, Translator, Corner, AxisIndex> elements_less(translator);
element_axis_corner_less<element_type, Translator, indexable_tag, Corner, AxisIndex> elements_less(translator);
std::sort(elements_copy.begin(), elements_copy.end(), elements_less); // MAY THROW, BASIC (copy)
// init outputs
@@ -106,7 +132,7 @@ struct choose_split_axis_and_index_for_corner
template <typename Parameters, typename Box, size_t AxisIndex, typename ElementIndexableTag>
struct choose_split_axis_and_index_for_axis
{
//BOOST_STATIC_ASSERT(0);
BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (ElementIndexableTag));
};
template <typename Parameters, typename Box, size_t AxisIndex>
@@ -227,7 +253,7 @@ struct choose_split_axis_and_index
Parameters,
Box,
Dimension - 1,
typename index::detail::traits::tag<element_indexable_type>::type
typename tag<element_indexable_type>::type
>::apply(elements, corner, index, sum_of_margins, overlap_val, content_val, parameters, translator); // MAY THROW, STRONG
if ( sum_of_margins < smallest_sum_of_margins )
@@ -267,7 +293,7 @@ struct choose_split_axis_and_index<Parameters, Box, 1>
Parameters,
Box,
0,
typename index::detail::traits::tag<element_indexable_type>::type
typename tag<element_indexable_type>::type
>::apply(elements, choosen_corner, choosen_index, smallest_sum_of_margins, smallest_overlap, smallest_content, parameters, translator); // MAY THROW
}
};
@@ -289,7 +315,10 @@ struct partial_sort
BOOST_GEOMETRY_INDEX_ASSERT(axis == Dimension - 1, "unexpected axis value");
typedef typename Elements::value_type element_type;
element_axis_corner_less<element_type, Translator, Corner, Dimension - 1> less(tr);
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename tag<indexable_type>::type indexable_tag;
element_axis_corner_less<element_type, Translator, indexable_tag, Corner, Dimension - 1> less(tr);
std::partial_sort(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy)
}
}
@@ -307,7 +336,10 @@ struct partial_sort<Corner, 1>
BOOST_GEOMETRY_INDEX_ASSERT(axis == 0, "unexpected axis value");
typedef typename Elements::value_type element_type;
element_axis_corner_less<element_type, Translator, Corner, 0> less(tr);
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename tag<indexable_type>::type indexable_tag;
element_axis_corner_less<element_type, Translator, indexable_tag, Corner, 0> less(tr);
std::partial_sort(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy)
}
};
@@ -323,7 +355,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
typedef typename Options::parameters_type parameters_type;
static const size_t dimension = index::detail::traits::dimension<Box>::value;
static const size_t dimension = dimension<Box>::value;
typedef typename index::detail::default_margin_result<Box>::type margin_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
@@ -353,7 +385,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
rstar::choose_split_axis_and_index<
typename Options::parameters_type,
Box,
index::detail::traits::dimension<Box>::value
dimension
>::apply(elements1,
split_axis, split_corner, split_index,
smallest_sum_of_margins, smallest_overlap, smallest_content,
@@ -361,7 +393,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
// TODO: awulkiew - get rid of following static_casts?
BOOST_GEOMETRY_INDEX_ASSERT(split_axis < index::detail::traits::dimension<Box>::value, "unexpected value");
BOOST_GEOMETRY_INDEX_ASSERT(split_axis < dimension, "unexpected value");
BOOST_GEOMETRY_INDEX_ASSERT(split_corner == static_cast<size_t>(min_corner) || split_corner == static_cast<size_t>(max_corner), "unexpected value");
BOOST_GEOMETRY_INDEX_ASSERT(parameters.get_min_elements() <= split_index && split_index <= parameters.get_max_elements() - parameters.get_min_elements() + 1, "unexpected value");

View File

@@ -11,8 +11,6 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP
#include <boost/geometry/index/detail/indexable.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
namespace utilities {
@@ -26,7 +24,7 @@ struct gl_draw_point
template <typename Point>
struct gl_draw_point<Point, 2>
{
static inline void apply(Point const& p, typename index::detail::traits::coordinate_type<Point>::type z)
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);
@@ -41,7 +39,7 @@ struct gl_draw_box
template <typename Box>
struct gl_draw_box<Box, 2>
{
static inline void apply(Box const& b, typename index::detail::traits::coordinate_type<Box>::type z)
static inline void apply(Box const& b, typename coordinate_type<Box>::type z)
{
glBegin(GL_LINE_LOOP);
glVertex3f(geometry::get<min_corner, 0>(b), geometry::get<min_corner, 1>(b), z);
@@ -60,9 +58,9 @@ struct gl_draw_indexable
template <typename Indexable>
struct gl_draw_indexable<Indexable, box_tag>
{
static const size_t dimension = index::detail::traits::dimension<Indexable>::value;
static const size_t dimension = dimension<Indexable>::value;
static inline void apply(Indexable const& i, typename index::detail::traits::coordinate_type<Indexable>::type z)
static inline void apply(Indexable const& i, typename coordinate_type<Indexable>::type z)
{
gl_draw_box<Indexable, dimension>::apply(i, z);
}
@@ -71,9 +69,9 @@ struct gl_draw_indexable<Indexable, box_tag>
template <typename Indexable>
struct gl_draw_indexable<Indexable, point_tag>
{
static const size_t dimension = index::detail::traits::dimension<Indexable>::value;
static const size_t dimension = dimension<Indexable>::value;
static inline void apply(Indexable const& i, typename index::detail::traits::coordinate_type<Indexable>::type z)
static inline void apply(Indexable const& i, typename coordinate_type<Indexable>::type z)
{
gl_draw_point<Indexable, dimension>::apply(i, z);
}
@@ -82,11 +80,11 @@ struct gl_draw_indexable<Indexable, point_tag>
} // namespace dispatch
template <typename Indexable> inline
void gl_draw_indexable(Indexable const& i, typename index::detail::traits::coordinate_type<Indexable>::type z)
void gl_draw_indexable(Indexable const& i, typename coordinate_type<Indexable>::type z)
{
dispatch::gl_draw_indexable<
Indexable,
typename index::detail::traits::tag<Indexable>::type
typename tag<Indexable>::type
>::apply(i, z);
}
@@ -105,7 +103,7 @@ struct gl_draw : public rtree::visitor<Value, typename Options::parameters_type,
inline gl_draw(Translator const& t,
size_t level_first = 0,
size_t level_last = (std::numeric_limits<size_t>::max)(),
typename index::detail::traits::coordinate_type<Box>::type z_coord_level_multiplier = 1
typename coordinate_type<Box>::type z_coord_level_multiplier = 1
)
: tr(t)
, level_f(level_first)
@@ -182,7 +180,7 @@ struct gl_draw : public rtree::visitor<Value, typename Options::parameters_type,
Translator const& tr;
size_t level_f;
size_t level_l;
typename index::detail::traits::coordinate_type<Box>::type z_mul;
typename coordinate_type<Box>::type z_mul;
size_t level;
};
@@ -193,7 +191,7 @@ template <typename Rtree> inline
void gl_draw(Rtree const& tree,
size_t level_first = 0,
size_t level_last = (std::numeric_limits<size_t>::max)(),
typename index::detail::traits::coordinate_type<
typename coordinate_type<
typename Rtree::bounds_type
>::type z_coord_level_multiplier = 1
)

View File

@@ -71,7 +71,7 @@ struct print_indexable
template <typename Indexable>
struct print_indexable<Indexable, box_tag>
{
static const size_t dimension = index::detail::traits::dimension<Indexable>::value;
static const size_t dimension = dimension<Indexable>::value;
static inline void apply(std::ostream &os, Indexable const& i)
{
@@ -86,7 +86,7 @@ struct print_indexable<Indexable, box_tag>
template <typename Indexable>
struct print_indexable<Indexable, point_tag>
{
static const size_t dimension = index::detail::traits::dimension<Indexable>::value;
static const size_t dimension = dimension<Indexable>::value;
static inline void apply(std::ostream &os, Indexable const& i)
{
@@ -103,7 +103,7 @@ void print_indexable(std::ostream & os, Indexable const& i)
{
dispatch::print_indexable<
Indexable,
typename geometry::traits::tag<Indexable>::type
typename tag<Indexable>::type
>::apply(os, i);
}

View File

@@ -12,7 +12,6 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_STATISTICS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_STATISTICS_HPP
#include <boost/geometry/index/detail/indexable.hpp>
#include <algorithm>
#include <tuple>

View File

@@ -29,7 +29,6 @@
#include <boost/geometry/index/indexable.hpp>
#include <boost/geometry/index/equal_to.hpp>
#include <boost/geometry/index/detail/indexable.hpp>
#include <boost/geometry/index/detail/translator.hpp>
#include <boost/geometry/index/predicates.hpp>
@@ -143,7 +142,14 @@ public:
>::type indexable_type;
/*! \brief The Box type used by the R-tree. */
typedef typename index::detail::default_box_type<indexable_type>::type bounds_type;
typedef geometry::model::box<
geometry::model::point<
typename coordinate_type<indexable_type>::type,
dimension<indexable_type>::value,
typename coordinate_system<indexable_type>::type
>
>
bounds_type;
private: