mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-17 13:52:09 +00:00
[index][equals] Add the support for Segments as Indexables in the rtree.
This commit also adds the support for equals(Segment, Segment). During the creation of the rtree all metrics are calculated for Segments viewed as bounding Boxes. During the querying Segments are passed into the BG algorithms. This commit also fixes a compilation error related to the calculation of the Box/Box intersection in the index::detail::intersection_content(). Add indexed_point_view<> which allows to see Boxes and Segments as one of the Points. Move normalized_view<> to views/detail. Add index::detail::bounded_view<> which allows to see simple Geometry e.g. a Segment as its bounding Geometry e.g. a Box. TODO/RECONSIDER: 1. This commit adds return_ref_or_bounds() which returns const& for Points and Boxes and bounding Box view for Segment. The resulting object is then passed into various algorithms like covered_by() or within(). Whenever possible the algorithms should be implemented for the input parameters and the call to return_ref_or_bounds() removed. 2. It's possible that for Segments metrics (like the amount of overlap in the leaf node) could be calculated differently than for Boxes and naiive conversion to bounding Boxes is not fully correct. 3. The way how bounded_view<> works may be not correct for non-cartesian CS. Now, for Segments it just picks MIN and MAX coordinates on the fly which may not be ok e.g. for Segments defined in the spherical CS because of the "winding" of the coordinates.
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
#include <boost/geometry/algorithms/detail/relate/boundary_checker.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/follow_helpers.hpp>
|
||||
|
||||
#include <boost/geometry/views/normalized_view.hpp>
|
||||
#include <boost/geometry/views/detail/normalized_view.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014 Oracle and/or its affiliates.
|
||||
@@ -43,12 +44,13 @@
|
||||
#include <boost/geometry/util/select_most_precise.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/equals/collect_vectors.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/relate.hpp>
|
||||
|
||||
#include <boost/geometry/views/detail/indexed_point_view.hpp>
|
||||
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/relate/relate.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
@@ -87,6 +89,28 @@ struct box_box<DimensionCount, DimensionCount>
|
||||
};
|
||||
|
||||
|
||||
struct segment_segment
|
||||
{
|
||||
template <typename Segment1, typename Segment2>
|
||||
static inline bool apply(Segment1 const& segment1, Segment2 const& segment2)
|
||||
{
|
||||
return ( equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 0>(segment1),
|
||||
indexed_point_view<Segment2 const, 0>(segment2) )
|
||||
&& equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 1>(segment1),
|
||||
indexed_point_view<Segment2 const, 1>(segment2) )
|
||||
) || ( equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 0>(segment1),
|
||||
indexed_point_view<Segment2 const, 1>(segment2) )
|
||||
&& equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 1>(segment1),
|
||||
indexed_point_view<Segment2 const, 0>(segment2) )
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct area_check
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
@@ -250,6 +274,11 @@ struct equals<Polygon, Box, polygon_tag, box_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
template <typename Segment1, typename Segment2, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<Segment1, Segment2, segment_tag, segment_tag, DimensionCount, Reverse>
|
||||
: detail::equals::segment_segment
|
||||
{};
|
||||
|
||||
template <typename LineString1, typename LineString2, bool Reverse>
|
||||
struct equals<LineString1, LineString2, linestring_tag, linestring_tag, 2, Reverse>
|
||||
//: detail::equals::equals_by_collection<detail::equals::length_check>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// n-dimensional bounds
|
||||
//
|
||||
// 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
|
||||
@@ -11,6 +11,8 @@
|
||||
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_BOUNDS_HPP
|
||||
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_BOUNDS_HPP
|
||||
|
||||
#include <boost/geometry/index/detail/bounded_view.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index { namespace detail {
|
||||
|
||||
namespace dispatch {
|
||||
@@ -27,6 +29,16 @@ struct bounds
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry, typename Bounds>
|
||||
struct bounds<Geometry, Bounds, segment_tag, box_tag>
|
||||
{
|
||||
static inline void apply(Geometry const& g, Bounds & b)
|
||||
{
|
||||
index::detail::bounded_view<Geometry, Bounds> v(g);
|
||||
geometry::convert(v, b);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
|
||||
template <typename Geometry, typename Bounds>
|
||||
@@ -36,6 +48,43 @@ inline void bounds(Geometry const& g, Bounds & b)
|
||||
dispatch::bounds<Geometry, Bounds>::apply(g, b);
|
||||
}
|
||||
|
||||
namespace dispatch {
|
||||
|
||||
template <typename Geometry,
|
||||
typename TagGeometry = typename geometry::tag<Geometry>::type>
|
||||
struct return_ref_or_bounds
|
||||
{
|
||||
typedef Geometry const& result_type;
|
||||
|
||||
static inline result_type apply(Geometry const& g)
|
||||
{
|
||||
return g;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct return_ref_or_bounds<Geometry, segment_tag>
|
||||
{
|
||||
typedef typename point_type<Geometry>::type point_type;
|
||||
typedef geometry::model::box<point_type> bounds_type;
|
||||
typedef index::detail::bounded_view<Geometry, bounds_type> result_type;
|
||||
|
||||
static inline result_type apply(Geometry const& g)
|
||||
{
|
||||
return result_type(g);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
|
||||
template <typename Geometry>
|
||||
inline
|
||||
typename dispatch::return_ref_or_bounds<Geometry>::result_type
|
||||
return_ref_or_bounds(Geometry const& g)
|
||||
{
|
||||
return dispatch::return_ref_or_bounds<Geometry>::apply(g);
|
||||
}
|
||||
|
||||
}}}} // namespace boost::geometry::index::detail
|
||||
|
||||
#endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_BOUNDS_HPP
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// boxes union/intersection area/volume
|
||||
//
|
||||
// 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
|
||||
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_INTERSECTION_CONTENT_HPP
|
||||
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_INTERSECTION_CONTENT_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/intersection_box_box.hpp>
|
||||
#include <boost/geometry/algorithms/intersection.hpp>
|
||||
#include <boost/geometry/strategies/intersection.hpp>
|
||||
#include <boost/geometry/index/detail/algorithms/content.hpp>
|
||||
|
||||
@@ -26,12 +26,7 @@ inline typename default_content_result<Box>::type intersection_content(Box const
|
||||
if ( geometry::intersects(box1, box2) )
|
||||
{
|
||||
Box box_intersection;
|
||||
|
||||
strategy_intersection_empty dummy;
|
||||
geometry::detail::intersection::intersection_box_box
|
||||
<
|
||||
0, geometry::dimension<Box>::value
|
||||
>::apply(box1, box2, box_intersection, dummy);
|
||||
geometry::intersection(box1, box2, box_intersection);
|
||||
return detail::content(box_intersection);
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// n-dimensional box's / point validity check
|
||||
//
|
||||
// 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
|
||||
@@ -66,6 +66,15 @@ struct is_valid<Indexable, box_tag>
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Indexable>
|
||||
struct is_valid<Indexable, segment_tag>
|
||||
{
|
||||
static inline bool apply(Indexable const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
|
||||
template <typename Indexable>
|
||||
|
||||
185
include/boost/geometry/index/detail/bounded_view.hpp
Normal file
185
include/boost/geometry/index/detail/bounded_view.hpp
Normal file
@@ -0,0 +1,185 @@
|
||||
// Boost.Geometry Index
|
||||
//
|
||||
// This view makes possible to treat some simple primitives as its bounding geometry
|
||||
// e.g. box, nsphere, etc.
|
||||
//
|
||||
// Copyright (c) 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)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_BOUNDED_VIEW_HPP
|
||||
#define BOOST_GEOMETRY_INDEX_DETAIL_BOUNDED_VIEW_HPP
|
||||
|
||||
namespace boost { namespace geometry {
|
||||
|
||||
namespace index { namespace detail {
|
||||
|
||||
template <typename Geometry,
|
||||
typename BoundingGeometry,
|
||||
typename Tag = typename geometry::tag<Geometry>::type,
|
||||
typename BoundingTag = typename geometry::tag<BoundingGeometry>::type>
|
||||
struct bounded_view
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG(
|
||||
(false),
|
||||
NOT_IMPLEMENTED_FOR_THOSE_GEOMETRIES,
|
||||
(BoundingTag, Tag));
|
||||
};
|
||||
|
||||
|
||||
// Segment -> Box
|
||||
|
||||
template <typename Segment, typename Box>
|
||||
struct bounded_view<Segment, Box, segment_tag, box_tag>
|
||||
{
|
||||
public:
|
||||
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
|
||||
|
||||
explicit bounded_view(Segment const& segment)
|
||||
: m_segment(segment)
|
||||
{}
|
||||
|
||||
template <std::size_t Dimension>
|
||||
inline coordinate_type get_min() const
|
||||
{
|
||||
return boost::numeric_cast<coordinate_type>(
|
||||
(std::min)( geometry::get<0, Dimension>(m_segment),
|
||||
geometry::get<1, Dimension>(m_segment) ) );
|
||||
}
|
||||
|
||||
template <std::size_t Dimension>
|
||||
inline coordinate_type get_max() const
|
||||
{
|
||||
return boost::numeric_cast<coordinate_type>(
|
||||
(std::max)( geometry::get<0, Dimension>(m_segment),
|
||||
geometry::get<1, Dimension>(m_segment) ) );
|
||||
}
|
||||
|
||||
private:
|
||||
Segment const& m_segment;
|
||||
};
|
||||
|
||||
// Box -> Box
|
||||
|
||||
template <typename BoxIn, typename Box>
|
||||
struct bounded_view<BoxIn, Box, box_tag, box_tag>
|
||||
{
|
||||
public:
|
||||
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
|
||||
|
||||
explicit bounded_view(BoxIn const& box)
|
||||
: m_box(box)
|
||||
{}
|
||||
|
||||
template <std::size_t Dimension>
|
||||
inline coordinate_type get_min() const
|
||||
{
|
||||
return boost::numeric_cast<coordinate_type>(
|
||||
geometry::get<min_corner, Dimension>(m_box) );
|
||||
}
|
||||
|
||||
template <std::size_t Dimension>
|
||||
inline coordinate_type get_max() const
|
||||
{
|
||||
return boost::numeric_cast<coordinate_type>(
|
||||
geometry::get<max_corner, Dimension>(m_box) );
|
||||
}
|
||||
|
||||
private:
|
||||
BoxIn const& m_box;
|
||||
};
|
||||
|
||||
// Point -> Box
|
||||
|
||||
template <typename Point, typename Box>
|
||||
struct bounded_view<Point, Box, point_tag, box_tag>
|
||||
{
|
||||
public:
|
||||
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
|
||||
|
||||
explicit bounded_view(Point const& point)
|
||||
: m_point(point)
|
||||
{}
|
||||
|
||||
template <std::size_t Dimension>
|
||||
inline coordinate_type get_min() const
|
||||
{
|
||||
return boost::numeric_cast<coordinate_type>(
|
||||
geometry::get<Dimension>(m_point) );
|
||||
}
|
||||
|
||||
template <std::size_t Dimension>
|
||||
inline coordinate_type get_max() const
|
||||
{
|
||||
return boost::numeric_cast<coordinate_type>(
|
||||
geometry::get<Dimension>(m_point) );
|
||||
}
|
||||
|
||||
private:
|
||||
Point const& m_point;
|
||||
};
|
||||
|
||||
}} // namespace index::detail
|
||||
|
||||
// XXX -> Box
|
||||
|
||||
#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
|
||||
namespace traits
|
||||
{
|
||||
|
||||
template <typename Geometry, typename Box, typename Tag>
|
||||
struct tag< index::detail::bounded_view<Geometry, Box, Tag, box_tag> >
|
||||
{
|
||||
typedef box_tag type;
|
||||
};
|
||||
|
||||
template <typename Segment, typename Box, typename Tag>
|
||||
struct point_type< index::detail::bounded_view<Segment, Box, Tag, box_tag> >
|
||||
{
|
||||
typedef typename point_type<Box>::type type;
|
||||
};
|
||||
|
||||
template <typename Segment, typename Box, typename Tag, std::size_t Dimension>
|
||||
struct indexed_access<index::detail::bounded_view<Segment, Box, Tag, box_tag>,
|
||||
min_corner, Dimension>
|
||||
{
|
||||
typedef index::detail::bounded_view<Segment, Box, Tag, box_tag> box_type;
|
||||
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
|
||||
|
||||
static inline coordinate_type get(box_type const& b)
|
||||
{
|
||||
return b.template get_min<Dimension>();
|
||||
}
|
||||
|
||||
//static inline void set(box_type & b, coordinate_type const& value)
|
||||
//{
|
||||
// BOOST_ASSERT(false);
|
||||
//}
|
||||
};
|
||||
|
||||
template <typename Segment, typename Box, typename Tag, std::size_t Dimension>
|
||||
struct indexed_access<index::detail::bounded_view<Segment, Box, Tag, box_tag>,
|
||||
max_corner, Dimension>
|
||||
{
|
||||
typedef index::detail::bounded_view<Segment, Box, Tag, box_tag> box_type;
|
||||
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
|
||||
|
||||
static inline coordinate_type get(box_type const& b)
|
||||
{
|
||||
return b.template get_max<Dimension>();
|
||||
}
|
||||
|
||||
//static inline void set(box_type & b, coordinate_type const& value)
|
||||
//{
|
||||
// BOOST_ASSERT(false);
|
||||
//}
|
||||
};
|
||||
|
||||
} // namespace traits
|
||||
#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_INDEX_DETAIL_BOUNDED_VIEW_HPP
|
||||
@@ -3,7 +3,7 @@
|
||||
// R-tree linear split algorithm implementation
|
||||
//
|
||||
// Copyright (c) 2008 Federico J. Fernandez.
|
||||
// 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
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <boost/type_traits/is_unsigned.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/algorithms/content.hpp>
|
||||
#include <boost/geometry/index/detail/bounded_view.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/rtree/node/node.hpp>
|
||||
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
|
||||
@@ -75,12 +76,6 @@ inline R difference(T const& from, T const& to)
|
||||
|
||||
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;
|
||||
@@ -92,6 +87,10 @@ struct find_greatest_normalized_separation<Elements, Parameters, Translator, box
|
||||
coordinate_type
|
||||
>::type separation_type;
|
||||
|
||||
typedef typename geometry::point_type<indexable_type>::type point_type;
|
||||
typedef geometry::model::box<point_type> bounds_type;
|
||||
typedef index::detail::bounded_view<indexable_type, bounds_type> bounded_view_type;
|
||||
|
||||
static inline void apply(Elements const& elements,
|
||||
Parameters const& parameters,
|
||||
Translator const& translator,
|
||||
@@ -104,15 +103,18 @@ struct find_greatest_normalized_separation<Elements, Parameters, Translator, box
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements");
|
||||
|
||||
// find the lowest low, highest high
|
||||
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));
|
||||
bounded_view_type bounded_indexable_0(rtree::element_indexable(elements[0], translator));
|
||||
coordinate_type lowest_low = geometry::get<min_corner, DimensionIndex>(bounded_indexable_0);
|
||||
coordinate_type highest_high = geometry::get<max_corner, DimensionIndex>(bounded_indexable_0);
|
||||
|
||||
// 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 = 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));
|
||||
bounded_view_type bounded_indexable(rtree::element_indexable(elements[i], translator));
|
||||
coordinate_type min_coord = geometry::get<min_corner, DimensionIndex>(bounded_indexable);
|
||||
coordinate_type max_coord = geometry::get<max_corner, DimensionIndex>(bounded_indexable);
|
||||
|
||||
if ( max_coord < lowest_high )
|
||||
{
|
||||
@@ -129,10 +131,12 @@ struct find_greatest_normalized_separation<Elements, Parameters, Translator, box
|
||||
|
||||
// find the highest low
|
||||
size_t highest_low_index = lowest_high_index == 0 ? 1 : 0;
|
||||
coordinate_type highest_low = geometry::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[highest_low_index], translator));
|
||||
bounded_view_type bounded_indexable_hl(rtree::element_indexable(elements[highest_low_index], translator));
|
||||
coordinate_type highest_low = geometry::get<min_corner, DimensionIndex>(bounded_indexable_hl);
|
||||
for ( size_t i = highest_low_index ; i < elements_count ; ++i )
|
||||
{
|
||||
coordinate_type min_coord = geometry::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[i], translator));
|
||||
bounded_view_type bounded_indexable(rtree::element_indexable(elements[i], translator));
|
||||
coordinate_type min_coord = geometry::get<min_corner, DimensionIndex>(bounded_indexable);
|
||||
if ( highest_low < min_coord &&
|
||||
i != lowest_high_index )
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// R-tree quadratic split algorithm implementation
|
||||
//
|
||||
// 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
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <boost/geometry/index/detail/algorithms/content.hpp>
|
||||
#include <boost/geometry/index/detail/algorithms/union_content.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/bounded_view.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/rtree/node/node.hpp>
|
||||
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
|
||||
#include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
|
||||
@@ -34,6 +36,7 @@ struct pick_seeds
|
||||
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;
|
||||
typedef index::detail::bounded_view<indexable_type, box_type> bounded_indexable_view;
|
||||
|
||||
static inline void apply(Elements const& elements,
|
||||
Parameters const& parameters,
|
||||
@@ -61,7 +64,11 @@ struct pick_seeds
|
||||
detail::bounds(ind1, enlarged_box);
|
||||
geometry::expand(enlarged_box, ind2);
|
||||
|
||||
content_type free_content = (index::detail::content(enlarged_box) - index::detail::content(ind1)) - index::detail::content(ind2);
|
||||
bounded_indexable_view bounded_ind1(ind1);
|
||||
bounded_indexable_view bounded_ind2(ind2);
|
||||
content_type free_content = ( index::detail::content(enlarged_box)
|
||||
- index::detail::content(bounded_ind1) )
|
||||
- index::detail::content(bounded_ind2);
|
||||
|
||||
if ( greatest_free_content < free_content )
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// R-tree R*-tree split algorithm implementation
|
||||
//
|
||||
// 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
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <boost/geometry/index/detail/algorithms/union_content.hpp>
|
||||
#include <boost/geometry/index/detail/algorithms/margin.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/bounded_view.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/rtree/node/node.hpp>
|
||||
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
|
||||
#include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
|
||||
@@ -28,7 +30,27 @@ namespace rstar {
|
||||
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));
|
||||
typedef typename rtree::element_indexable_type<Element, Translator>::type indexable_type;
|
||||
typedef typename geometry::point_type<indexable_type>::type point_type;
|
||||
typedef geometry::model::box<point_type> bounds_type;
|
||||
typedef index::detail::bounded_view<indexable_type, bounds_type> bounded_view_type;
|
||||
|
||||
public:
|
||||
element_axis_corner_less(Translator const& tr)
|
||||
: m_tr(tr)
|
||||
{}
|
||||
|
||||
bool operator()(Element const& e1, Element const& e2) const
|
||||
{
|
||||
bounded_view_type bounded_ind1(rtree::element_indexable(e1, m_tr));
|
||||
bounded_view_type bounded_ind2(rtree::element_indexable(e2, m_tr));
|
||||
|
||||
return geometry::get<Corner, AxisIndex>(bounded_ind1)
|
||||
< geometry::get<Corner, AxisIndex>(bounded_ind2);
|
||||
}
|
||||
|
||||
private:
|
||||
Translator const& m_tr;
|
||||
};
|
||||
|
||||
template <typename Element, typename Translator, size_t Corner, size_t AxisIndex>
|
||||
@@ -129,14 +151,14 @@ 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_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (ElementIndexableTag));
|
||||
//};
|
||||
|
||||
template <typename Parameters, typename Box, size_t AxisIndex, typename ElementIndexableTag>
|
||||
struct choose_split_axis_and_index_for_axis
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (ElementIndexableTag));
|
||||
};
|
||||
|
||||
template <typename Parameters, typename Box, size_t AxisIndex>
|
||||
struct choose_split_axis_and_index_for_axis<Parameters, Box, AxisIndex, box_tag>
|
||||
{
|
||||
typedef typename index::detail::default_margin_result<Box>::type margin_type;
|
||||
typedef typename index::detail::default_content_result<Box>::type content_type;
|
||||
@@ -403,11 +425,15 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
|
||||
|
||||
// TODO: awulkiew - check if std::partial_sort produces the same result as std::sort
|
||||
if ( split_corner == static_cast<size_t>(min_corner) )
|
||||
{
|
||||
rstar::partial_sort<min_corner, dimension>
|
||||
::apply(elements_copy, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
|
||||
}
|
||||
else
|
||||
{
|
||||
rstar::partial_sort<max_corner, dimension>
|
||||
::apply(elements_copy, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
|
||||
}
|
||||
|
||||
BOOST_TRY
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// R-tree boxes validating visitor implementation
|
||||
//
|
||||
// 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
|
||||
@@ -89,7 +89,9 @@ public:
|
||||
}
|
||||
|
||||
Box box_exp;
|
||||
geometry::convert(m_tr(elements.front()), box_exp);
|
||||
geometry::convert(
|
||||
index::detail::return_ref_or_bounds(m_tr(elements.front())),
|
||||
box_exp);
|
||||
for(typename elements_type::const_iterator it = elements.begin() + 1;
|
||||
it != elements.end() ; ++it)
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// R-tree count visitor implementation
|
||||
//
|
||||
// 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
|
||||
@@ -36,8 +36,12 @@ struct count
|
||||
for (typename elements_type::const_iterator it = elements.begin();
|
||||
it != elements.end(); ++it)
|
||||
{
|
||||
if ( geometry::covered_by(indexable, it->first) )
|
||||
if ( geometry::covered_by(
|
||||
return_ref_or_bounds(indexable),
|
||||
it->first) )
|
||||
{
|
||||
rtree::apply_visitor(*this, *it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,8 +88,12 @@ struct count<Value, Value, Options, Translator, Box, Allocators>
|
||||
for (typename elements_type::const_iterator it = elements.begin();
|
||||
it != elements.end(); ++it)
|
||||
{
|
||||
if ( geometry::covered_by(tr(value), it->first) )
|
||||
if ( geometry::covered_by(
|
||||
return_ref_or_bounds(tr(value)),
|
||||
it->first) )
|
||||
{
|
||||
rtree::apply_visitor(*this, *it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// R-tree removing visitor implementation
|
||||
//
|
||||
// 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
|
||||
@@ -68,7 +68,9 @@ public:
|
||||
size_t child_node_index = 0;
|
||||
for ( ; child_node_index < children.size() ; ++child_node_index )
|
||||
{
|
||||
if ( geometry::covered_by(m_translator(m_value), children[child_node_index].first) )
|
||||
if ( geometry::covered_by(
|
||||
return_ref_or_bounds(m_translator(m_value)),
|
||||
children[child_node_index].first) )
|
||||
{
|
||||
// next traversing step
|
||||
traverse_apply_visitor(n, child_node_index); // MAY THROW
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
|
||||
namespace boost { namespace geometry { namespace index { namespace detail {
|
||||
|
||||
template <typename Geometry, typename Tag>
|
||||
template <typename Geometry,
|
||||
typename Tag = typename geometry::tag<Geometry>::type>
|
||||
struct equals
|
||||
{
|
||||
inline static bool apply(Geometry const& g1, Geometry const& g2)
|
||||
@@ -38,12 +39,9 @@ struct tuple_equals
|
||||
inline static bool apply(Tuple const& t1, Tuple const& t2)
|
||||
{
|
||||
typedef typename boost::tuples::element<I, Tuple>::type T;
|
||||
return
|
||||
equals<
|
||||
T, typename geometry::traits::tag<T>::type
|
||||
>::apply(boost::get<I>(t1), boost::get<I>(t2))
|
||||
&&
|
||||
tuple_equals<Tuple, I+1, N>::apply(t1, t2);
|
||||
|
||||
return equals<T>::apply(boost::get<I>(t1), boost::get<I>(t2))
|
||||
&& tuple_equals<Tuple, I+1, N>::apply(t1, t2);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -56,6 +54,12 @@ struct tuple_equals<Tuple, I, I>
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: Consider this: Since equal_to<> is using geometry::equals() it's possible that
|
||||
// two compared Indexables are not exactly the same! They will be spatially equal
|
||||
// but not strictly equal. Consider 2 Segments with reversed order of points.
|
||||
// Therefore it's possible that during the Value removal different value will be
|
||||
// removed than the one that was passed.
|
||||
|
||||
/*!
|
||||
\brief The function object comparing Values.
|
||||
|
||||
@@ -66,7 +70,8 @@ This template is also specialized for std::pair<T1, T2> and boost::tuple<...>.
|
||||
\tparam Value The type of objects which are compared by this function object.
|
||||
\tparam IsIndexable If true, Values are compared using boost::geometry::equals() functions.
|
||||
*/
|
||||
template <typename Value, bool IsIndexable = is_indexable<Value>::value>
|
||||
template <typename Value,
|
||||
bool IsIndexable = is_indexable<Value>::value>
|
||||
struct equal_to
|
||||
{
|
||||
/*! \brief The type of result returned by function object. */
|
||||
@@ -81,7 +86,7 @@ struct equal_to
|
||||
*/
|
||||
inline bool operator()(Value const& l, Value const& r) const
|
||||
{
|
||||
return detail::equals<Value, typename geometry::traits::tag<Value>::type>::apply(l ,r);
|
||||
return detail::equals<Value>::apply(l ,r);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -109,10 +114,8 @@ struct equal_to<std::pair<T1, T2>, false>
|
||||
*/
|
||||
inline bool operator()(std::pair<T1, T2> const& l, std::pair<T1, T2> const& r) const
|
||||
{
|
||||
typedef detail::equals<T1, typename geometry::traits::tag<T1>::type> equals1;
|
||||
typedef detail::equals<T2, typename geometry::traits::tag<T2>::type> equals2;
|
||||
|
||||
return equals1::apply(l.first, r.first) && equals2::apply(l.second, r.second);
|
||||
return detail::equals<T1>::apply(l.first, r.first)
|
||||
&& detail::equals<T2>::apply(l.second, r.second);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -160,12 +163,9 @@ struct std_tuple_equals
|
||||
inline static bool apply(Tuple const& t1, Tuple const& t2)
|
||||
{
|
||||
typedef typename std::tuple_element<I, Tuple>::type T;
|
||||
return
|
||||
equals<
|
||||
T, typename geometry::traits::tag<T>::type
|
||||
>::apply(std::get<I>(t1), std::get<I>(t2))
|
||||
&&
|
||||
std_tuple_equals<Tuple, I+1, N>::apply(t1, t2);
|
||||
|
||||
return equals<T>::apply(std::get<I>(t1), std::get<I>(t2))
|
||||
&& std_tuple_equals<Tuple, I+1, N>::apply(t1, t2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -22,6 +22,9 @@ struct is_indexable_impl<Point, geometry::point_tag> { static const bool value =
|
||||
template <typename Box>
|
||||
struct is_indexable_impl<Box, geometry::box_tag> { static const bool value = true; };
|
||||
|
||||
template <typename Segment>
|
||||
struct is_indexable_impl<Segment, geometry::segment_tag> { static const bool value = true; };
|
||||
|
||||
template <typename Indexable>
|
||||
struct is_indexable
|
||||
{
|
||||
@@ -42,6 +45,12 @@ and std::tuple<Indexable, ...>.
|
||||
template <typename Value, bool IsIndexable = is_indexable<Value>::value>
|
||||
struct indexable
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG(
|
||||
(detail::is_indexable<Value>::value),
|
||||
NOT_VALID_INDEXABLE_TYPE,
|
||||
(Value)
|
||||
);
|
||||
|
||||
/*! \brief The type of result returned by function object. */
|
||||
typedef Value const& result_type;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// R-tree implementation
|
||||
//
|
||||
// Copyright (c) 2008 Federico J. Fernandez.
|
||||
// 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
|
||||
@@ -55,6 +55,9 @@
|
||||
//#include <boost/geometry/multi/algorithms/disjoint.hpp>
|
||||
//#include <boost/geometry/multi/algorithms/equals.hpp>
|
||||
//#include <boost/geometry/multi/algorithms/within.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/point.hpp>
|
||||
#include <boost/geometry/geometries/box.hpp>
|
||||
// END
|
||||
|
||||
#include <boost/geometry/index/detail/config_begin.hpp>
|
||||
@@ -139,8 +142,8 @@ Predefined algorithms with run-time parameters are:
|
||||
\par IndexableGetter
|
||||
The object of IndexableGetter type translates from Value to Indexable each time r-tree requires it. Which means that this
|
||||
operation is done for each Value access. Therefore the IndexableGetter should return the Indexable by
|
||||
const reference instead of a value. Default one can translate all types adapted to Point
|
||||
or Box concepts (called Indexables). It also handles <tt>std::pair<Indexable, T></tt> and
|
||||
const reference instead of a value. Default one can translate all types adapted to Point, Box or Segment
|
||||
concepts (called Indexables). It also handles <tt>std::pair<Indexable, T></tt> and
|
||||
<tt>boost::tuple<Indexable, ...></tt>. For example, if <tt>std::pair<Box, int></tt> is stored in the
|
||||
container, the default IndexableGetter translates from <tt>std::pair<Box, int> const&</tt> to <tt>Box const&</tt>.
|
||||
|
||||
|
||||
112
include/boost/geometry/views/detail/indexed_point_view.hpp
Normal file
112
include/boost/geometry/views/detail/indexed_point_view.hpp
Normal file
@@ -0,0 +1,112 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland
|
||||
|
||||
// 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_VIEWS_DETAIL_INDEXED_POINT_VIEW_HPP
|
||||
#define BOOST_GEOMETRY_VIEWS_DETAIL_INDEXED_POINT_VIEW_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
#include <boost/geometry/core/coordinate_system.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Geometry, std::size_t Index>
|
||||
class indexed_point_view
|
||||
{
|
||||
indexed_point_view & operator=(indexed_point_view const&);
|
||||
|
||||
public:
|
||||
typedef typename geometry::point_type<Geometry>::type point_type;
|
||||
typedef typename geometry::coordinate_type<Geometry>::type coordinate_type;
|
||||
|
||||
indexed_point_view(Geometry & geometry)
|
||||
: m_geometry(geometry)
|
||||
{}
|
||||
|
||||
template <std::size_t Dimension>
|
||||
inline coordinate_type get() const
|
||||
{
|
||||
return geometry::get<Index, Dimension>(m_geometry);
|
||||
}
|
||||
|
||||
template <std::size_t Dimension>
|
||||
inline void set(coordinate_type const& value)
|
||||
{
|
||||
geometry::set<Index, Dimension>(m_geometry, value);
|
||||
}
|
||||
|
||||
private:
|
||||
Geometry & m_geometry;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
|
||||
namespace traits
|
||||
{
|
||||
|
||||
template <typename Geometry, std::size_t Index>
|
||||
struct tag< detail::indexed_point_view<Geometry, Index> >
|
||||
{
|
||||
typedef point_tag type;
|
||||
};
|
||||
|
||||
template <typename Geometry, std::size_t Index>
|
||||
struct coordinate_type< detail::indexed_point_view<Geometry, Index> >
|
||||
{
|
||||
typedef typename geometry::coordinate_type<Geometry>::type type;
|
||||
};
|
||||
|
||||
template <typename Geometry, std::size_t Index>
|
||||
struct coordinate_system< detail::indexed_point_view<Geometry, Index> >
|
||||
{
|
||||
typedef typename geometry::coordinate_system<Geometry>::type type;
|
||||
};
|
||||
|
||||
template <typename Geometry, std::size_t Index>
|
||||
struct dimension< detail::indexed_point_view<Geometry, Index> >
|
||||
: geometry::dimension<Geometry>
|
||||
{};
|
||||
|
||||
template<typename Geometry, std::size_t Index, std::size_t Dimension>
|
||||
struct access< detail::indexed_point_view<Geometry, Index>, Dimension >
|
||||
{
|
||||
typedef typename geometry::coordinate_type<Geometry>::type coordinate_type;
|
||||
|
||||
static inline coordinate_type get(
|
||||
detail::indexed_point_view<Geometry, Index> const& p)
|
||||
{
|
||||
return p.template get<Dimension>();
|
||||
}
|
||||
|
||||
static inline void set(
|
||||
detail::indexed_point_view<Geometry, Index> & p,
|
||||
coordinate_type const& value)
|
||||
{
|
||||
p.template set<Dimension>(value);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace traits
|
||||
#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_VIEWS_DETAIL_INDEXED_POINT_VIEW_HPP
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#ifndef BOOST_GEOMETRY_VIEWS_NORMALIZED_VIEW_HPP
|
||||
#define BOOST_GEOMETRY_VIEWS_NORMALIZED_VIEW_HPP
|
||||
#ifndef BOOST_GEOMETRY_VIEWS_DETAIL_NORMALIZED_VIEW_HPP
|
||||
#define BOOST_GEOMETRY_VIEWS_DETAIL_NORMALIZED_VIEW_HPP
|
||||
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
@@ -113,4 +113,4 @@ private:
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_VIEWS_NORMALIZED_VIEW_HPP
|
||||
#endif // BOOST_GEOMETRY_VIEWS_DETAIL_NORMALIZED_VIEW_HPP
|
||||
Reference in New Issue
Block a user