mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-10 23:42:12 +00:00
R*tree implementation based on boost::variant
[SVN r70531]
This commit is contained in:
96
.gitattributes
vendored
Normal file
96
.gitattributes
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
* text=auto !eol svneol=native#text/plain
|
||||
*.gitattributes text svneol=native#text/plain
|
||||
|
||||
# Scriptish formats
|
||||
*.bat text svneol=native#text/plain
|
||||
*.bsh text svneol=native#text/x-beanshell
|
||||
*.cgi text svneol=native#text/plain
|
||||
*.cmd text svneol=native#text/plain
|
||||
*.js text svneol=native#text/javascript
|
||||
*.php text svneol=native#text/x-php
|
||||
*.pl text svneol=native#text/x-perl
|
||||
*.pm text svneol=native#text/x-perl
|
||||
*.py text svneol=native#text/x-python
|
||||
*.sh eol=lf svneol=LF#text/x-sh
|
||||
configure eol=lf svneol=LF#text/x-sh
|
||||
|
||||
# Image formats
|
||||
*.bmp binary svneol=unset#image/bmp
|
||||
*.gif binary svneol=unset#image/gif
|
||||
*.ico binary svneol=unset#image/ico
|
||||
*.jpeg binary svneol=unset#image/jpeg
|
||||
*.jpg binary svneol=unset#image/jpeg
|
||||
*.png binary svneol=unset#image/png
|
||||
*.tif binary svneol=unset#image/tiff
|
||||
*.tiff binary svneol=unset#image/tiff
|
||||
*.svg text svneol=native#image/svg%2Bxml
|
||||
|
||||
# Data formats
|
||||
*.pdf binary svneol=unset#application/pdf
|
||||
*.avi binary svneol=unset#video/avi
|
||||
*.doc binary svneol=unset#application/msword
|
||||
*.dsp text svneol=crlf#text/plain
|
||||
*.dsw text svneol=crlf#text/plain
|
||||
*.eps binary svneol=unset#application/postscript
|
||||
*.gz binary svneol=unset#application/gzip
|
||||
*.mov binary svneol=unset#video/quicktime
|
||||
*.mp3 binary svneol=unset#audio/mpeg
|
||||
*.ppt binary svneol=unset#application/vnd.ms-powerpoint
|
||||
*.ps binary svneol=unset#application/postscript
|
||||
*.psd binary svneol=unset#application/photoshop
|
||||
*.rdf binary svneol=unset#text/rdf
|
||||
*.rss text svneol=unset#text/xml
|
||||
*.rtf binary svneol=unset#text/rtf
|
||||
*.sln text svneol=native#text/plain
|
||||
*.swf binary svneol=unset#application/x-shockwave-flash
|
||||
*.tgz binary svneol=unset#application/gzip
|
||||
*.vcproj text svneol=native#text/xml
|
||||
*.vcxproj text svneol=native#text/xml
|
||||
*.vsprops text svneol=native#text/xml
|
||||
*.wav binary svneol=unset#audio/wav
|
||||
*.xls binary svneol=unset#application/vnd.ms-excel
|
||||
*.zip binary svneol=unset#application/zip
|
||||
|
||||
# Text formats
|
||||
.htaccess text svneol=native#text/plain
|
||||
*.bbk text svneol=native#text/xml
|
||||
*.cmake text svneol=native#text/plain
|
||||
*.css text svneol=native#text/css
|
||||
*.dtd text svneol=native#text/xml
|
||||
*.htm text svneol=native#text/html
|
||||
*.html text svneol=native#text/html
|
||||
*.ini text svneol=native#text/plain
|
||||
*.log text svneol=native#text/plain
|
||||
*.mak text svneol=native#text/plain
|
||||
*.qbk text svneol=native#text/plain
|
||||
*.rst text svneol=native#text/plain
|
||||
*.sql text svneol=native#text/x-sql
|
||||
*.txt text svneol=native#text/plain
|
||||
*.xhtml text svneol=native#text/xhtml%2Bxml
|
||||
*.xml text svneol=native#text/xml
|
||||
*.xsd text svneol=native#text/xml
|
||||
*.xsl text svneol=native#text/xml
|
||||
*.xslt text svneol=native#text/xml
|
||||
*.xul text svneol=native#text/xul
|
||||
*.yml text svneol=native#text/plain
|
||||
boost-no-inspect text svneol=native#text/plain
|
||||
CHANGES text svneol=native#text/plain
|
||||
COPYING text svneol=native#text/plain
|
||||
INSTALL text svneol=native#text/plain
|
||||
Jamfile text svneol=native#text/plain
|
||||
Jamroot text svneol=native#text/plain
|
||||
Jamfile.v2 text svneol=native#text/plain
|
||||
Jamrules text svneol=native#text/plain
|
||||
Makefile* text svneol=native#text/plain
|
||||
README text svneol=native#text/plain
|
||||
TODO text svneol=native#text/plain
|
||||
|
||||
# Code formats
|
||||
*.c text svneol=native#text/plain
|
||||
*.cpp text svneol=native#text/plain
|
||||
*.h text svneol=native#text/plain
|
||||
*.hpp text svneol=native#text/plain
|
||||
*.ipp text svneol=native#text/plain
|
||||
*.tpp text svneol=native#text/plain
|
||||
*.jam text svneol=native#text/plain
|
||||
*.java text svneol=native#text/plain
|
||||
58
include/boost/geometry/extensions/index/algorithms/area.hpp
Normal file
58
include/boost/geometry/extensions/index/algorithms/area.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.SpatialIndex - n-dimensional box's area/volume
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_ALGORITHMS_AREA_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_ALGORITHMS_AREA_HPP
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
template <typename Box>
|
||||
struct area_result
|
||||
{
|
||||
typedef typename select_most_precise<
|
||||
typename coordinate_type<Box>::type,
|
||||
long double
|
||||
>::type type;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Box, size_t CurrentDimension>
|
||||
struct area_for_each_dimension
|
||||
{
|
||||
BOOST_STATIC_ASSERT(0 < CurrentDimension);
|
||||
BOOST_STATIC_ASSERT(CurrentDimension <= traits::dimension<Box>::value);
|
||||
|
||||
static inline typename area_result<Box>::type apply(Box const& b)
|
||||
{
|
||||
return area_for_each_dimension<Box, CurrentDimension - 1>::apply(b) *
|
||||
( geometry::get<max_corner, CurrentDimension - 1>(b) - geometry::get<min_corner, CurrentDimension - 1>(b) );
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box>
|
||||
struct area_for_each_dimension<Box, 1>
|
||||
{
|
||||
static inline typename area_result<Box>::type apply(Box const& b)
|
||||
{
|
||||
return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Box>
|
||||
typename area_result<Box>::type area(Box const& b)
|
||||
{
|
||||
return detail::area_for_each_dimension<Box, traits::dimension<Box>::value>::apply(b);
|
||||
}
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_ALGORITHMS_AREA_HPP
|
||||
102
include/boost/geometry/extensions/index/algorithms/margin.hpp
Normal file
102
include/boost/geometry/extensions/index/algorithms/margin.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.SpatialIndex - n-dimensional box's margin value, 2d perimeter, 3d surface, etc...
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_ALGORITHMS_MARGIN_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_ALGORITHMS_MARGIN_HPP
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
template <typename Box>
|
||||
struct margin_result
|
||||
{
|
||||
typedef typename select_most_precise<
|
||||
typename coordinate_type<Box>::type,
|
||||
long double
|
||||
>::type type;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Box, size_t CurrentDimension, size_t EdgeDimension>
|
||||
struct margin_for_each_edge
|
||||
{
|
||||
BOOST_STATIC_ASSERT(0 < CurrentDimension);
|
||||
BOOST_STATIC_ASSERT(0 < EdgeDimension);
|
||||
|
||||
static inline typename margin_result<Box>::type apply(Box const& b)
|
||||
{
|
||||
return margin_for_each_edge<Box, CurrentDimension, EdgeDimension - 1>::apply(b) *
|
||||
( geometry::get<max_corner, EdgeDimension - 1>(b) - geometry::get<min_corner, EdgeDimension - 1>(b) );
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box, size_t CurrentDimension>
|
||||
struct margin_for_each_edge<Box, CurrentDimension, CurrentDimension>
|
||||
{
|
||||
BOOST_STATIC_ASSERT(0 < CurrentDimension);
|
||||
|
||||
static inline typename margin_result<Box>::type apply(Box const& b)
|
||||
{
|
||||
return margin_for_each_edge<Box, CurrentDimension, CurrentDimension - 1>::apply(b);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box, size_t CurrentDimension>
|
||||
struct margin_for_each_edge<Box, CurrentDimension, 1>
|
||||
{
|
||||
BOOST_STATIC_ASSERT(0 < CurrentDimension);
|
||||
|
||||
static inline typename margin_result<Box>::type apply(Box const& b)
|
||||
{
|
||||
return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box>
|
||||
struct margin_for_each_edge<Box, 1, 1>
|
||||
{
|
||||
static inline typename margin_result<Box>::type apply(Box const& b)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box, size_t CurrentDimension>
|
||||
struct margin_for_each_dimension
|
||||
{
|
||||
BOOST_STATIC_ASSERT(0 < CurrentDimension);
|
||||
BOOST_STATIC_ASSERT(CurrentDimension <= traits::dimension<Box>::value);
|
||||
|
||||
static inline typename margin_result<Box>::type apply(Box const& b)
|
||||
{
|
||||
return margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
|
||||
2 * margin_for_each_edge<Box, CurrentDimension, traits::dimension<Box>::value>::apply(b);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box>
|
||||
struct margin_for_each_dimension<Box, 1>
|
||||
{
|
||||
static inline typename margin_result<Box>::type apply(Box const& b)
|
||||
{
|
||||
return 2 * margin_for_each_edge<Box, 1, traits::dimension<Box>::value>::apply(b);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Box>
|
||||
typename margin_result<Box>::type margin(Box const& b)
|
||||
{
|
||||
return detail::margin_for_each_dimension<Box, traits::dimension<Box>::value>::apply(b);
|
||||
}
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_ALGORITHMS_MARGIN_HPP
|
||||
@@ -0,0 +1,34 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.SpatialIndex - n-dimensional area/volume of boxes intersecion/overlap
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_ALGORITHMS_OVERLAP_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_ALGORITHMS_OVERLAP_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/intersection.hpp>
|
||||
#include <boost/geometry/extensions/index/algorithms/area.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
template <typename Box>
|
||||
struct overlap_result
|
||||
{
|
||||
typedef typename area_result<Box>::type type;
|
||||
};
|
||||
|
||||
template <typename Box>
|
||||
typename overlap_result<Box>::type overlap(Box const& b1, Box const& b2)
|
||||
{
|
||||
Box inters;
|
||||
geometry::intersection(b1, b2, inters);
|
||||
return index::area(inters);
|
||||
}
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_ALGORITHMS_OVERLAP_HPP
|
||||
@@ -0,0 +1,32 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.SpatialIndex - boxes union/intersection area/volume
|
||||
//
|
||||
// Copyright 2008 Federico J. Fernandez.
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_ALGORITHMS_UNION_AREA_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_ALGORITHMS_UNION_AREA_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/expand.hpp>
|
||||
#include <boost/geometry/extensions/index/algorithms/area.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
/**
|
||||
* \brief Compute the area of the union of b1 and b2
|
||||
*/
|
||||
template <typename Box, typename Geometry>
|
||||
inline typename area_result<Box>::type union_area(Box const& b, Geometry const& g)
|
||||
{
|
||||
Box expanded_box(b);
|
||||
geometry::expand(expanded_box, g);
|
||||
return index::area(expanded_box);
|
||||
}
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_ALGORITHMS_UNION_AREA_HPP
|
||||
@@ -0,0 +1,62 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.SpatialIndex - default indexes parameters
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_DEFAULT_PARAMETER_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_DEFAULT_PARAMETER_HPP
|
||||
|
||||
#include <boost/geometry/geometries/point.hpp>
|
||||
#include <boost/geometry/geometries/box.hpp>
|
||||
#include <boost/geometry/extensions/index/translator/def.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
// TODO: awulkiew - move this elsewhere
|
||||
struct default_parameter {};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Indexable>
|
||||
struct geometry_box_type
|
||||
{
|
||||
typedef geometry::model::box<
|
||||
geometry::model::point<
|
||||
typename index::traits::coordinate_type<Indexable>::type,
|
||||
index::traits::dimension<Indexable>::value,
|
||||
typename index::traits::coordinate_system<Indexable>::type
|
||||
>
|
||||
> type;
|
||||
};
|
||||
|
||||
template <typename Value, typename Translator>
|
||||
struct default_translator_type
|
||||
{
|
||||
typedef Translator type;
|
||||
};
|
||||
template <typename Value>
|
||||
struct default_translator_type<Value, default_parameter>
|
||||
{
|
||||
typedef translator::def<Value> type;
|
||||
};
|
||||
|
||||
template <typename Indexable, typename Box>
|
||||
struct default_box_type
|
||||
{
|
||||
typedef Box type;
|
||||
};
|
||||
template <typename Indexable>
|
||||
struct default_box_type<Indexable, default_parameter>
|
||||
{
|
||||
typedef typename detail::geometry_box_type<Indexable>::type type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_DEFAULT_PARAMETER_HPP
|
||||
@@ -0,0 +1,78 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.SpatialIndex - nearest neighbour filter implementation
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_FILTERS_NEAREST_FILTER_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_FILTERS_NEAREST_FILTER_HPP
|
||||
|
||||
namespace boost { namespace geometry { namespace index { namespace filters {
|
||||
|
||||
template <typename SpacialIndex>
|
||||
class nearest_filter
|
||||
{
|
||||
public:
|
||||
typedef int* iterator;
|
||||
typedef const int* const_iterator;
|
||||
|
||||
template <typename Point>
|
||||
nearest_filter(
|
||||
SpacialIndex const&,
|
||||
Point const&,
|
||||
typename traits::coordinate_type<Point>::type const&
|
||||
)
|
||||
{}
|
||||
|
||||
iterator begin() { return 0; }
|
||||
iterator end() { return 0; }
|
||||
const_iterator begin() const { return 0; }
|
||||
const_iterator end() const { return 0; }
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename Point>
|
||||
class nearest_filtered
|
||||
{
|
||||
public:
|
||||
explicit nearest_filtered(
|
||||
Point const& p,
|
||||
typename traits::coordinate_type<Point>::type const& distance)
|
||||
: m_point(p), m_distance(distance) {}
|
||||
|
||||
Point const& point() const { return m_point; }
|
||||
|
||||
typename traits::coordinate_type<Point>::type const&
|
||||
distance() const { return m_distance; }
|
||||
|
||||
private:
|
||||
Point m_point;
|
||||
typename traits::coordinate_type<Point>::type m_distance;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Point>
|
||||
detail::nearest_filtered<Point> nearest_filtered(
|
||||
Point const& p,
|
||||
typename traits::coordinate_type<Point>::type const& distance)
|
||||
{
|
||||
return detail::nearest_filtered<Point>(p, distance);
|
||||
}
|
||||
|
||||
}}}} // namespace boost::geometry::index::filters
|
||||
|
||||
template<typename SpacialIndex, typename Point>
|
||||
boost::geometry::index::filters::nearest_filter<SpacialIndex>
|
||||
operator|(
|
||||
SpacialIndex const& si,
|
||||
boost::geometry::index::filters::detail::nearest_filtered<Point> const& f)
|
||||
{
|
||||
return boost::geometry::index::filters::nearest_filter<SpacialIndex>(si, f.point(), f.distance());
|
||||
}
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_FILTERS_NEAREST_FILTER_HPP
|
||||
@@ -0,0 +1,63 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.SpatialIndex - box query filter implementation
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_FILTERS_SPACIAL_FILTER_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_FILTERS_SPACIAL_FILTER_HPP
|
||||
|
||||
namespace boost { namespace geometry { namespace index { namespace filters {
|
||||
|
||||
template <typename SpacialIndex>
|
||||
class spatial_filter
|
||||
{
|
||||
public:
|
||||
typedef int* iterator;
|
||||
typedef const int* const_iterator;
|
||||
|
||||
template <typename Geometry>
|
||||
spatial_filter(SpacialIndex const&, Geometry const&) {}
|
||||
|
||||
iterator begin() { return 0; }
|
||||
iterator end() { return 0; }
|
||||
const_iterator begin() const { return 0; }
|
||||
const_iterator end() const { return 0; }
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename Geometry>
|
||||
class spatially_filtered
|
||||
{
|
||||
public:
|
||||
explicit spatially_filtered(Geometry const& geom) : m_geom(geom) {}
|
||||
Geometry const& geometry() const { return m_geom; }
|
||||
|
||||
private:
|
||||
Geometry const& m_geom;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Geometry>
|
||||
detail::spatially_filtered<Geometry> spatially_filtered(Geometry const& geom)
|
||||
{
|
||||
return detail::spatially_filtered<Geometry>(geom);
|
||||
}
|
||||
|
||||
}}}} // namespace boost::geometry::index::filters
|
||||
|
||||
template<typename SpacialIndex, typename Geometry>
|
||||
boost::geometry::index::filters::spatial_filter<SpacialIndex>
|
||||
operator|(
|
||||
SpacialIndex const& si,
|
||||
boost::geometry::index::filters::detail::spatially_filtered<Geometry> const& f)
|
||||
{
|
||||
return boost::geometry::index::filters::spatial_filter<SpacialIndex>(si, f.geometry());
|
||||
}
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_FILTERS_SPACIAL_FILTER_HPP
|
||||
160
include/boost/geometry/extensions/index/indexable.hpp
Normal file
160
include/boost/geometry/extensions/index/indexable.hpp
Normal file
@@ -0,0 +1,160 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.SpatialIndex - indexable traits and functions
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_INDEXABLE_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_INDEXABLE_HPP
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
namespace dispatch {
|
||||
|
||||
// Distinguish between indexables and other geometries
|
||||
|
||||
template <typename Geometry, typename GeometryTag>
|
||||
struct indexable_type
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <typename Point>
|
||||
struct indexable_type<Point, geometry::point_tag>
|
||||
{
|
||||
typedef Point type;
|
||||
};
|
||||
|
||||
template <typename Box>
|
||||
struct indexable_type<Box, geometry::box_tag>
|
||||
{
|
||||
typedef Box type;
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
|
||||
namespace traits
|
||||
{
|
||||
|
||||
template <typename Indexable>
|
||||
struct indexable_type
|
||||
{
|
||||
typedef typename dispatch::indexable_type<
|
||||
Indexable,
|
||||
typename geometry::traits::tag<Indexable>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
} // namespace traits
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
} // 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
|
||||
|
||||
namespace detail {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_INDEXABLE_HPP
|
||||
52
include/boost/geometry/extensions/index/rtree/filters.hpp
Normal file
52
include/boost/geometry/extensions/index/rtree/filters.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.SpatialIndex - rtree queries filters implementation
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_RTREE_FILTERS_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_FILTERS_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/geometry/extensions/index/filters/spacial_filter.hpp>
|
||||
#include <boost/geometry/extensions/index/filters/nearest_filter.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
template <typename Value, typename Translator, typename Box, typename Tag>
|
||||
class rtree;
|
||||
|
||||
namespace filters {
|
||||
|
||||
template <typename Value, typename Translator, typename Box, typename Tag>
|
||||
class spatial_filter< index::rtree<Value, Translator, Box, Tag> >
|
||||
{
|
||||
public:
|
||||
typedef typename std::vector<Value>::iterator iterator;
|
||||
typedef typename std::vector<Value>::const_iterator const_iterator;
|
||||
|
||||
template <typename Geometry>
|
||||
spatial_filter(index::rtree<Value, Translator, Box, Tag> const& rtree, Geometry const& geom)
|
||||
{
|
||||
m_result = rtree.find(geom);
|
||||
}
|
||||
|
||||
iterator begin() { return m_result.begin(); }
|
||||
iterator end() { return m_result.end(); }
|
||||
const_iterator begin() const { return m_result.begin(); }
|
||||
const_iterator end() const { return m_result.end(); }
|
||||
|
||||
private:
|
||||
std::vector<Value> m_result;
|
||||
};
|
||||
|
||||
} // namespace filters
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_FILTERS_HPP
|
||||
@@ -0,0 +1,16 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.Index - R*-tree
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_RTREE_RSTAR_RSTAR_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RSTAR_RSTAR_HPP
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/rstar/tags.hpp>
|
||||
#include <boost/geometry/extensions/index/rtree/rstar/rtree_insert.hpp>
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RSTAR_RSTAR_HPP
|
||||
@@ -0,0 +1,729 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.Index - R*-tree insert algorithm implementation
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_RTREE_RSTAR_RTREE_INSERT_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RSTAR_RTREE_INSERT_HPP
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
#include <boost/geometry/extensions/index/algorithms/area.hpp>
|
||||
#include <boost/geometry/extensions/index/algorithms/margin.hpp>
|
||||
#include <boost/geometry/extensions/index/algorithms/overlap.hpp>
|
||||
#include <boost/geometry/extensions/index/algorithms/union_area.hpp>
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/rtree_node.hpp>
|
||||
#include <boost/geometry/extensions/index/rtree/visitors/rtree_insert.hpp>
|
||||
#include <boost/geometry/extensions/index/rtree/visitors/rtree_is_leaf.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
namespace visitors {
|
||||
|
||||
// ----------------------------------------------------------------------------- //
|
||||
// rstar/choose_next_node
|
||||
// ----------------------------------------------------------------------------- //
|
||||
|
||||
// TODO: awulkiew - it's possible that goodness values may be used to choose next node
|
||||
|
||||
// rtree choose_next_node algorithm for rstar variant
|
||||
|
||||
template <typename Value, typename Box>
|
||||
class rtree_rstar_choose_next_node
|
||||
{
|
||||
typedef typename index::detail::rtree_node<Value, Box, rtree_rstar_tag>::type node;
|
||||
typedef typename index::detail::rtree_internal_node<Value, Box, rtree_rstar_tag>::type internal_node;
|
||||
typedef typename index::detail::rtree_leaf<Value, Box, rtree_rstar_tag>::type leaf;
|
||||
|
||||
typedef typename internal_node::children_type children_type;
|
||||
|
||||
public:
|
||||
// TODO: awulkiew - alternative lower-cost version of overlap calculation may be used (branch_areas)
|
||||
// TODO: awulkiew - further optimization: don't calculate area with the overlap, calculate it only if
|
||||
// overlap < smallest_overlap (and current area must be stored) OR
|
||||
// overlap == smallest_overlap (and area must be compared)
|
||||
template <typename Indexable>
|
||||
static inline size_t apply(internal_node & n, Indexable const& indexable)
|
||||
{
|
||||
assert(!n.children.empty());
|
||||
|
||||
bool has_leaves = boost::apply_visitor(
|
||||
visitors::rtree_is_leaf<Value, Box, rtree_rstar_tag>(),
|
||||
*n.children.front().second);
|
||||
|
||||
if ( !has_leaves )
|
||||
return impl<internal_node_areas>(n, indexable);
|
||||
else
|
||||
return impl<branch_areas>(n, indexable);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Areas, typename Indexable>
|
||||
static inline size_t impl(internal_node & n, Indexable const& indexable)
|
||||
{
|
||||
typedef typename children_type::iterator children_iterator;
|
||||
|
||||
//assert(!n.children.empty());
|
||||
|
||||
children_iterator temp_it = n.children.begin();
|
||||
children_iterator child_it = temp_it;
|
||||
Areas min_areas(n.children, child_it, indexable);
|
||||
|
||||
for (children_iterator it = ++temp_it;
|
||||
it != n.children.end(); ++it)
|
||||
{
|
||||
Areas areas(n.children, it, indexable);
|
||||
|
||||
if ( areas < min_areas )
|
||||
{
|
||||
child_it = it;
|
||||
min_areas = areas;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: awulkiew - switch to indexes in the whole class?
|
||||
return child_it - n.children.begin();
|
||||
}
|
||||
|
||||
struct branch_areas
|
||||
{
|
||||
typedef typename area_result<Box>::type area_type;
|
||||
|
||||
template <typename Indexable>
|
||||
inline branch_areas(children_type const& ch, typename children_type::iterator const& k_it, Indexable const& indexable)
|
||||
{
|
||||
overlap_area = 0;
|
||||
for (typename children_type::const_iterator it = ch.begin(); it != ch.end(); ++it)
|
||||
if ( it != k_it )
|
||||
overlap_area += index::overlap(k_it->first, it->first);
|
||||
|
||||
area = index::area(k_it->first);
|
||||
|
||||
diff_area = index::union_area(k_it->first, indexable) - area;
|
||||
}
|
||||
|
||||
inline bool operator<(branch_areas &a) const
|
||||
{
|
||||
return overlap_area < a.overlap_area ||
|
||||
( overlap_area == a.overlap_area && diff_area < a.diff_area ) ||
|
||||
( diff_area == a.diff_area && area < a.area );
|
||||
}
|
||||
|
||||
area_type overlap_area;
|
||||
area_type diff_area;
|
||||
area_type area;
|
||||
};
|
||||
|
||||
struct internal_node_areas
|
||||
{
|
||||
typedef typename area_result<Box>::type area_type;
|
||||
|
||||
template <typename Indexable>
|
||||
inline internal_node_areas(children_type const&, typename children_type::iterator const& k_it, Indexable const& indexable)
|
||||
{
|
||||
area = index::area(k_it->first);
|
||||
diff_area = index::union_area(k_it->first, indexable) - area;
|
||||
}
|
||||
|
||||
inline bool operator<(internal_node_areas &a) const
|
||||
{
|
||||
return diff_area < a.diff_area ||
|
||||
( diff_area == a.diff_area && area < a.area );
|
||||
}
|
||||
|
||||
area_type diff_area;
|
||||
area_type area;
|
||||
};
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- //
|
||||
// rstar/sorts
|
||||
// ----------------------------------------------------------------------------- //
|
||||
|
||||
// elements ids less comparator
|
||||
|
||||
template <typename Elements, typename Translator, size_t Corner, size_t AxisIndex>
|
||||
class rtree_rstar_elements_indexes_less
|
||||
{
|
||||
public:
|
||||
rtree_rstar_elements_indexes_less(Elements const& elements, Translator const& tr)
|
||||
: m_elements(elements), m_tr(tr)
|
||||
{}
|
||||
|
||||
bool operator()(size_t e1_index, size_t e2_index)
|
||||
{
|
||||
return
|
||||
index::detail::get<Corner, AxisIndex>(
|
||||
index::detail::rtree_element_indexable(m_elements[e1_index], m_tr)
|
||||
)
|
||||
<
|
||||
index::detail::get<Corner, AxisIndex>(
|
||||
index::detail::rtree_element_indexable(m_elements[e2_index], m_tr)
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
Elements const& m_elements;
|
||||
Translator const& m_tr;
|
||||
};
|
||||
|
||||
template <typename T, size_t Dimension>
|
||||
class rtree_rstar_vectors
|
||||
{
|
||||
public:
|
||||
inline rtree_rstar_vectors(size_t count)
|
||||
: m_count(count), m_ids(Dimension * 2 * count)
|
||||
{}
|
||||
|
||||
template <size_t AxisIndex, size_t Corner>
|
||||
inline typename std::vector<T>::iterator begin()
|
||||
{
|
||||
BOOST_STATIC_ASSERT(AxisIndex < Dimension);
|
||||
BOOST_STATIC_ASSERT(Corner < 2);
|
||||
return m_ids.begin() + ( AxisIndex * 2 + Corner ) * m_count;
|
||||
}
|
||||
|
||||
template <size_t AxisIndex, size_t Corner>
|
||||
inline typename std::vector<T>::iterator end()
|
||||
{
|
||||
BOOST_STATIC_ASSERT(AxisIndex < Dimension);
|
||||
BOOST_STATIC_ASSERT(Corner < 2);
|
||||
return m_ids.begin() + ( AxisIndex * 2 + Corner + 1) * m_count;
|
||||
}
|
||||
|
||||
template <size_t AxisIndex, size_t Corner>
|
||||
inline T const& get(size_t index) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT(AxisIndex < Dimension);
|
||||
BOOST_STATIC_ASSERT(Corner < 2);
|
||||
assert(index < m_count);
|
||||
return m_ids[( AxisIndex * 2 + Corner ) * m_count + index];
|
||||
}
|
||||
|
||||
template <size_t AxisIndex, size_t Corner>
|
||||
inline void set(size_t index, T const& v)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(AxisIndex < Dimension);
|
||||
BOOST_STATIC_ASSERT(Corner < 2);
|
||||
assert(index < m_count);
|
||||
m_ids[( AxisIndex * 2 + Corner ) * m_count + index] = v;
|
||||
}
|
||||
|
||||
inline T const& get(size_t axis, size_t corner, size_t index) const
|
||||
{
|
||||
assert(axis < Dimension);
|
||||
assert(corner < 2);
|
||||
assert(index < m_count);
|
||||
return m_ids[( axis * 2 + corner ) * m_count + index];
|
||||
}
|
||||
|
||||
inline size_t vector_size() const
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t m_count;
|
||||
std::vector<T> m_ids;
|
||||
};
|
||||
|
||||
// init indexes of elements and sort them
|
||||
|
||||
template <typename Elements, typename Translator, size_t Dimension>
|
||||
class rtree_rstar_sorts_fill_ids
|
||||
{
|
||||
BOOST_STATIC_ASSERT(0 < Dimension);
|
||||
|
||||
public:
|
||||
template <size_t D>
|
||||
static inline void apply(rtree_rstar_vectors<size_t, D> & ids, Elements const& elements, Translator const& tr)
|
||||
{
|
||||
rtree_rstar_sorts_fill_ids<Elements, Translator, Dimension - 1>::apply(ids, elements, tr);
|
||||
|
||||
fill<min_corner>(ids, elements, tr);
|
||||
fill<max_corner>(ids, elements, tr);
|
||||
}
|
||||
|
||||
private:
|
||||
template <size_t Corner, size_t D>
|
||||
static inline void fill(rtree_rstar_vectors<size_t, D> & ids, Elements const& elements, Translator const& tr)
|
||||
{
|
||||
for ( size_t i = 0 ; i < elements.size() ; ++i )
|
||||
ids.set<Dimension - 1, Corner>(i, i);
|
||||
|
||||
rtree_rstar_elements_indexes_less<Elements, Translator, Corner, Dimension - 1> less(elements, tr);
|
||||
std::sort(ids.begin<Dimension - 1, Corner>(), ids.end<Dimension - 1, Corner>(), less);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Elements, typename Translator>
|
||||
class rtree_rstar_sorts_fill_ids<Elements, Translator, 1>
|
||||
{
|
||||
public:
|
||||
template <size_t D>
|
||||
static inline void apply(rtree_rstar_vectors<size_t, D> & ids, Elements const& elements, Translator const& tr)
|
||||
{
|
||||
fill<min_corner>(ids, elements, tr);
|
||||
fill<max_corner>(ids, elements, tr);
|
||||
}
|
||||
|
||||
private:
|
||||
template <size_t Corner, size_t D>
|
||||
static inline void fill(rtree_rstar_vectors<size_t, D> & ids, Elements const& elements, Translator const& tr)
|
||||
{
|
||||
for ( size_t i = 0 ; i < elements.size() ; ++i )
|
||||
ids.set<0, Corner>(i, i);
|
||||
|
||||
rtree_rstar_elements_indexes_less<Elements, Translator, Corner, 0> less(elements, tr);
|
||||
std::sort(ids.begin<0, Corner>(), ids.end<0, Corner>(), less);
|
||||
}
|
||||
};
|
||||
|
||||
// sorts for each axis for min and max
|
||||
|
||||
template <typename Elements, typename Translator, size_t Dimension>
|
||||
class rtree_rstar_sorts
|
||||
{
|
||||
public:
|
||||
inline rtree_rstar_sorts(Elements const& elements, Translator const& tr)
|
||||
: m_elems(elements), m_tr(tr), m_ids(m_elems.size())
|
||||
{
|
||||
rtree_rstar_sorts_fill_ids<Elements, Translator, Dimension>::apply(m_ids, elements, tr);
|
||||
}
|
||||
|
||||
// TODO: awulkiew - should those methods be here? Just leave get_element?
|
||||
|
||||
template <size_t AxisIndex, size_t Corner>
|
||||
inline typename index::detail::rtree_element_indexable_type<typename Elements::value_type, Translator>::type const&
|
||||
get_indexable(size_t index) const
|
||||
{
|
||||
size_t id = m_ids.get<AxisIndex, Corner>(index);
|
||||
return index::detail::rtree_element_indexable(m_elems[id], m_tr);
|
||||
}
|
||||
|
||||
inline typename index::detail::rtree_element_indexable_type<typename Elements::value_type, Translator>::type const&
|
||||
get_indexable(size_t axis, size_t corner, size_t index) const
|
||||
{
|
||||
size_t id = m_ids.get(axis, corner, index);
|
||||
return index::detail::rtree_element_indexable(m_elems[id], m_tr);
|
||||
}
|
||||
|
||||
template <size_t AxisIndex, size_t Corner>
|
||||
inline typename Elements::value_type const& get_element(size_t index) const
|
||||
{
|
||||
size_t id = m_ids.get<AxisIndex, Corner>(index);
|
||||
return m_elems[id];
|
||||
}
|
||||
|
||||
inline typename Elements::value_type const& get_element(size_t axis, size_t corner, size_t index) const
|
||||
{
|
||||
size_t id = m_ids.get(axis, corner, index);
|
||||
return m_elems[id];
|
||||
}
|
||||
|
||||
inline size_t sort_size() const
|
||||
{
|
||||
return m_ids.vector_size();
|
||||
}
|
||||
|
||||
private:
|
||||
Elements const& m_elems;
|
||||
Translator const& m_tr;
|
||||
|
||||
rtree_rstar_vectors<size_t, Dimension> m_ids;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- //
|
||||
// rstar/goodness_values
|
||||
// ----------------------------------------------------------------------------- //
|
||||
|
||||
// calculate margins, areas and overlaps
|
||||
|
||||
template <typename Box, size_t AxisIndex, size_t Corner>
|
||||
class rtree_rstar_calculate_goodness_values_for_axis
|
||||
{
|
||||
typedef typename geometry::traits::coordinate_type<
|
||||
typename geometry::traits::point_type<Box>::type
|
||||
>::type coordinate_type;
|
||||
|
||||
static const size_t dimension = geometry::traits::dimension<
|
||||
typename geometry::traits::point_type<Box>::type
|
||||
>::value;
|
||||
|
||||
typedef typename area_result<Box>::type area_type;
|
||||
typedef typename margin_result<Box>::type margin_type;
|
||||
typedef typename overlap_result<Box>::type overlap_type;
|
||||
typedef boost::tuple<Box, Box, margin_type, overlap_type, area_type> goodness_type;
|
||||
|
||||
public:
|
||||
template <typename Elements, typename Translator>
|
||||
static inline void apply(
|
||||
rtree_rstar_vectors<goodness_type, dimension> & goodness_vectors,
|
||||
rtree_rstar_sorts<Elements, Translator, dimension> const& sorts,
|
||||
size_t min_elems,
|
||||
size_t max_elems)
|
||||
{
|
||||
assert(sorts.sort_size() == max_elems + 1);
|
||||
assert(goodness_vectors.vector_size() == max_elems - 2 * min_elems + 2);
|
||||
|
||||
size_t median_index_last = max_elems - min_elems + 2;
|
||||
size_t i = 0;
|
||||
for ( size_t median_index = min_elems ; median_index < median_index_last ; ++median_index, ++i )
|
||||
{
|
||||
Box left_box = calculate_box(sorts, 0, median_index);
|
||||
Box right_box = calculate_box(sorts, median_index, sorts.sort_size());
|
||||
|
||||
margin_type margin = index::margin(left_box) + index::margin(right_box);
|
||||
area_type area = index::area(left_box) + index::area(right_box);
|
||||
overlap_type overlap = index::overlap(left_box, right_box);
|
||||
|
||||
goodness_vectors.set<AxisIndex, Corner>(
|
||||
i,
|
||||
boost::make_tuple(left_box, right_box, margin, overlap, area));
|
||||
}
|
||||
}
|
||||
private:
|
||||
template <typename Elements, typename Translator>
|
||||
static inline Box calculate_box(
|
||||
rtree_rstar_sorts<Elements, Translator, dimension> const& sorts,
|
||||
size_t index_first,
|
||||
size_t index_last)
|
||||
{
|
||||
assert(index_first < index_last);
|
||||
|
||||
Box result;
|
||||
geometry::convert(sorts.template get_indexable<AxisIndex, Corner>(index_first), result);
|
||||
++index_first;
|
||||
for ( ; index_first < index_last ; ++index_first )
|
||||
geometry::expand(result, sorts.template get_indexable<AxisIndex, Corner>(index_first));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// calculate goodness values for all axis
|
||||
|
||||
template <typename Box, size_t Dimension>
|
||||
struct rtree_rstar_calculate_goodness_values
|
||||
{
|
||||
BOOST_STATIC_ASSERT(0 < Dimension);
|
||||
|
||||
typedef typename area_result<Box>::type area_type;
|
||||
typedef typename margin_result<Box>::type margin_type;
|
||||
typedef typename overlap_result<Box>::type overlap_type;
|
||||
typedef boost::tuple<Box, Box, margin_type, overlap_type, area_type> goodness_type;
|
||||
|
||||
template <typename Elements, typename Translator, size_t D>
|
||||
static inline void apply(
|
||||
rtree_rstar_vectors<goodness_type, D> & goodness_vectors,
|
||||
rtree_rstar_sorts<Elements, Translator, D> const& sorts,
|
||||
size_t min_elems,
|
||||
size_t max_elems)
|
||||
{
|
||||
rtree_rstar_calculate_goodness_values<Box, Dimension - 1>
|
||||
::apply(goodness_vectors, sorts, min_elems, max_elems);
|
||||
|
||||
rtree_rstar_calculate_goodness_values_for_axis<Box, Dimension - 1, min_corner>
|
||||
::apply(goodness_vectors, sorts, min_elems, max_elems);
|
||||
rtree_rstar_calculate_goodness_values_for_axis<Box, Dimension - 1, max_corner>
|
||||
::apply(goodness_vectors, sorts, min_elems, max_elems);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box>
|
||||
struct rtree_rstar_calculate_goodness_values<Box, 1>
|
||||
{
|
||||
typedef typename area_result<Box>::type area_type;
|
||||
typedef typename margin_result<Box>::type margin_type;
|
||||
typedef typename overlap_result<Box>::type overlap_type;
|
||||
typedef boost::tuple<Box, Box, margin_type, overlap_type, area_type> goodness_type;
|
||||
|
||||
template <typename Elements, typename Translator, size_t D>
|
||||
static inline void apply(
|
||||
rtree_rstar_vectors<goodness_type, D> & goodness_vectors,
|
||||
rtree_rstar_sorts<Elements, Translator, D> const& sorts,
|
||||
size_t min_elems,
|
||||
size_t max_elems)
|
||||
{
|
||||
rtree_rstar_calculate_goodness_values_for_axis<Box, 0, min_corner>
|
||||
::apply(goodness_vectors, sorts, min_elems, max_elems);
|
||||
rtree_rstar_calculate_goodness_values_for_axis<Box, 0, max_corner>
|
||||
::apply(goodness_vectors, sorts, min_elems, max_elems);
|
||||
}
|
||||
};
|
||||
|
||||
// goodness values
|
||||
|
||||
template <typename Elements, typename Translator, typename Box>
|
||||
class rtree_rstar_goodness_values
|
||||
{
|
||||
typedef typename geometry::traits::coordinate_type<
|
||||
typename geometry::traits::point_type<Box>::type
|
||||
>::type coordinate_type;
|
||||
|
||||
static const size_t dimension = geometry::traits::dimension<
|
||||
typename geometry::traits::point_type<Box>::type
|
||||
>::value;
|
||||
|
||||
typedef typename area_result<Box>::type area_type;
|
||||
typedef typename margin_result<Box>::type margin_type;
|
||||
typedef typename overlap_result<Box>::type overlap_type;
|
||||
typedef boost::tuple<Box, Box, margin_type, overlap_type, area_type> goodness_type;
|
||||
|
||||
public:
|
||||
inline rtree_rstar_goodness_values(
|
||||
Elements const& elements,
|
||||
Translator const& tr,
|
||||
size_t min_elems,
|
||||
size_t max_elems)
|
||||
: m_sorts(elements, tr)
|
||||
, m_goodness_vectors(max_elems - 2 * min_elems + 2)
|
||||
{
|
||||
rtree_rstar_calculate_goodness_values<Box, dimension>::apply(
|
||||
m_goodness_vectors, m_sorts, min_elems, max_elems);
|
||||
}
|
||||
|
||||
inline size_t elements_size() const
|
||||
{
|
||||
return m_sorts.sort_size();
|
||||
}
|
||||
|
||||
inline size_t goodnesses_size() const
|
||||
{
|
||||
return m_goodness_vectors.vector_size();
|
||||
}
|
||||
|
||||
inline goodness_type const& get_goodness(size_t axis, size_t corner, size_t index) const
|
||||
{
|
||||
return m_goodness_vectors.get(axis, corner, index);
|
||||
}
|
||||
|
||||
inline typename Elements::value_type const& get_element(size_t axis, size_t corner, size_t index) const
|
||||
{
|
||||
return m_sorts.get_element(axis, corner, index);
|
||||
}
|
||||
|
||||
private:
|
||||
rtree_rstar_sorts<Elements, Translator, dimension> m_sorts;
|
||||
rtree_rstar_vectors<goodness_type, dimension> m_goodness_vectors;
|
||||
};
|
||||
|
||||
template <typename Elements, typename Translator, typename Box>
|
||||
class rtree_rstar_choose_split_axis
|
||||
{
|
||||
typedef typename margin_result<Box>::type margin_type;
|
||||
public:
|
||||
static inline std::pair<size_t, size_t> apply(rtree_rstar_goodness_values<Elements, Translator, Box> const& gv)
|
||||
{
|
||||
std::pair<size_t, size_t> smallest_distr = std::make_pair(0, 0);
|
||||
margin_type smallest_margins_sum = calculate_margins_sum(0, 0, gv);
|
||||
|
||||
margin_type margins_sum = calculate_margins_sum(0, 1, gv);
|
||||
if ( margins_sum < smallest_margins_sum )
|
||||
{
|
||||
smallest_distr.second = 1;
|
||||
smallest_margins_sum = margins_sum;
|
||||
}
|
||||
|
||||
for ( size_t a = 1 ; a < traits::dimension<Box>::value ; ++a )
|
||||
{
|
||||
for ( size_t c = 0 ; c < 2 ; ++c )
|
||||
{
|
||||
margins_sum = calculate_margins_sum(a, c, gv);
|
||||
if ( margins_sum < smallest_margins_sum )
|
||||
{
|
||||
smallest_distr.first = a;
|
||||
smallest_distr.second = c;
|
||||
smallest_margins_sum = margins_sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
return smallest_distr;
|
||||
}
|
||||
private:
|
||||
static inline typename margin_result<Box>::type
|
||||
calculate_margins_sum(size_t axis, size_t corner, rtree_rstar_goodness_values<Elements, Translator, Box> const& gv)
|
||||
{
|
||||
typename margin_result<Box>::type margins_sum = 0;
|
||||
for ( size_t i = 0 ; i < gv.goodnesses_size() ; ++i )
|
||||
margins_sum += boost::get<2>(gv.get_goodness(axis, corner, i));
|
||||
return margins_sum;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Elements, typename Translator, typename Box>
|
||||
class rtree_rstar_choose_split_index
|
||||
{
|
||||
typedef typename area_result<Box>::type area_type;
|
||||
typedef typename overlap_result<Box>::type overlap_type;
|
||||
public:
|
||||
static inline size_t apply(rtree_rstar_goodness_values<Elements, Translator, Box> const& gv, size_t axis, size_t corner)
|
||||
{
|
||||
size_t smallest_index = 0;
|
||||
overlap_type smallest_overlap = boost::get<3>(gv.get_goodness(axis, corner, 0));
|
||||
overlap_type smallest_area = boost::get<4>(gv.get_goodness(axis, corner, 0));
|
||||
|
||||
for ( size_t i = 1 ; i < gv.goodnesses_size() ; ++i )
|
||||
{
|
||||
overlap_type overlap = boost::get<3>(gv.get_goodness(axis, corner, i));
|
||||
if ( overlap < smallest_overlap )
|
||||
{
|
||||
smallest_overlap = overlap;
|
||||
smallest_area = boost::get<4>(gv.get_goodness(axis, corner, i));
|
||||
smallest_index = i;
|
||||
}
|
||||
else if ( overlap == smallest_overlap )
|
||||
{
|
||||
area_type area = boost::get<4>(gv.get_goodness(axis, corner, i));
|
||||
if ( area < smallest_area )
|
||||
{
|
||||
smallest_area = area;
|
||||
smallest_index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return smallest_index;
|
||||
}
|
||||
};
|
||||
|
||||
// rtree insert routine for rstar variant
|
||||
|
||||
template <typename Value, typename Translator, typename Box>
|
||||
class rtree_insert<Value, Translator, Box, rtree_rstar_tag> : public boost::static_visitor<>
|
||||
{
|
||||
typedef typename index::detail::rtree_node<Value, Box, rtree_rstar_tag>::type node;
|
||||
typedef typename index::detail::rtree_internal_node<Value, Box, rtree_rstar_tag>::type internal_node;
|
||||
typedef typename index::detail::rtree_leaf<Value, Box, rtree_rstar_tag>::type leaf;
|
||||
|
||||
public:
|
||||
inline explicit rtree_insert(node* & root, Value const& v, size_t min_elements, size_t max_elements, Translator const& t)
|
||||
: m_value(v), m_tr(t), m_min_elems_per_node(min_elements), m_max_elems_per_node(max_elements)
|
||||
, m_root_node(root)
|
||||
, m_parent(0), m_current_child_index(0)
|
||||
{}
|
||||
|
||||
inline void operator()(internal_node & n)
|
||||
{
|
||||
// save previous traverse inputs and set new ones
|
||||
internal_node * parent_bckup = m_parent;
|
||||
m_parent = &n;
|
||||
size_t current_child_index_bckup = m_current_child_index;
|
||||
|
||||
// choose next node, where value insert traversing should go
|
||||
m_current_child_index = rtree_rstar_choose_next_node<Value, Box>::apply(n, m_tr(m_value));
|
||||
|
||||
// TODO: awulkiew - if reinsert is implemented this must be changed
|
||||
geometry::expand(n.children[m_current_child_index].first, m_tr(m_value));
|
||||
|
||||
// next traversing step
|
||||
boost::apply_visitor(*this, *n.children[m_current_child_index].second);
|
||||
|
||||
// restore previous traverse inputs
|
||||
m_parent = parent_bckup;
|
||||
m_current_child_index = current_child_index_bckup;
|
||||
|
||||
if ( m_max_elems_per_node < n.children.size() )
|
||||
{
|
||||
split(n);
|
||||
}
|
||||
}
|
||||
|
||||
inline void operator()(leaf & n)
|
||||
{
|
||||
n.values.push_back(m_value);
|
||||
|
||||
if ( m_max_elems_per_node < n.values.size() )
|
||||
{
|
||||
split(n);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Node>
|
||||
inline void split(Node & n)
|
||||
{
|
||||
typedef typename index::detail::rtree_elements_type<Node>::type elements_type;
|
||||
typedef typename elements_type::value_type element_type;
|
||||
|
||||
elements_type & elems = index::detail::get_elements(n);
|
||||
|
||||
rtree_rstar_goodness_values<elements_type, Translator, Box> gv(elems, m_tr, m_min_elems_per_node, m_max_elems_per_node);
|
||||
|
||||
std::pair<size_t, size_t> axis_and_corner =
|
||||
rtree_rstar_choose_split_axis<elements_type, Translator, Box>::apply(gv);
|
||||
size_t axis = axis_and_corner.first;
|
||||
size_t corner = axis_and_corner.second;
|
||||
|
||||
size_t choosen_index =
|
||||
rtree_rstar_choose_split_index<elements_type, Translator, Box>::apply(gv, axis, corner);
|
||||
|
||||
size_t median_index = m_min_elems_per_node + choosen_index;
|
||||
assert(median_index <= m_max_elems_per_node + 1 - m_min_elems_per_node);
|
||||
|
||||
// create new node
|
||||
node * right_node = rtree_create_node(Node());
|
||||
elements_type & new_elems = index::detail::get_elements(boost::get<Node>(*right_node));
|
||||
|
||||
// update new node's elements
|
||||
new_elems.reserve(m_max_elems_per_node + 1 - median_index);
|
||||
for ( size_t i = median_index ; i < m_max_elems_per_node + 1 ; ++i)
|
||||
new_elems.push_back(gv.get_element(axis, corner, i));
|
||||
|
||||
// fill temporary container with left node's elements
|
||||
elements_type left_elems;
|
||||
left_elems.reserve(median_index);
|
||||
for ( size_t i = 0 ; i < median_index ; ++i )
|
||||
left_elems.push_back(gv.get_element(axis, corner, i));
|
||||
// update old node's elements
|
||||
elems = left_elems;
|
||||
|
||||
if ( m_parent != 0 )
|
||||
{
|
||||
// update old node's box
|
||||
m_parent->children[m_current_child_index].first = boost::get<0>(gv.get_goodness(axis, corner, choosen_index));
|
||||
// add new node to the parent's children
|
||||
m_parent->children.push_back( std::make_pair(
|
||||
boost::get<1>(gv.get_goodness(axis, corner, choosen_index)), right_node ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(&n == boost::get<Node>(m_root_node));
|
||||
|
||||
// create new root and add nodes
|
||||
node * new_root = rtree_create_node(internal_node());
|
||||
|
||||
boost::get<internal_node>(*new_root).children.push_back(
|
||||
std::make_pair(boost::get<0>(gv.get_goodness(axis, corner, choosen_index)), m_root_node)
|
||||
);
|
||||
boost::get<internal_node>(*new_root).children.push_back(
|
||||
std::make_pair(boost::get<1>(gv.get_goodness(axis, corner, choosen_index)), right_node)
|
||||
);
|
||||
|
||||
m_root_node = new_root;
|
||||
}
|
||||
}
|
||||
|
||||
Value const& m_value;
|
||||
Translator const& m_tr;
|
||||
size_t m_min_elems_per_node;
|
||||
size_t m_max_elems_per_node;
|
||||
|
||||
node* & m_root_node;
|
||||
|
||||
// traversing input parameters
|
||||
internal_node *m_parent;
|
||||
size_t m_current_child_index;
|
||||
};
|
||||
|
||||
} // namespace visitors
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RSTAR_RTREE_INSERT_HPP
|
||||
19
include/boost/geometry/extensions/index/rtree/rstar/tags.hpp
Normal file
19
include/boost/geometry/extensions/index/rtree/rstar/tags.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.Index - R*-tree tags
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_RTREE_RSTAR_TAGS_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RSTAR_TAGS_HPP
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
struct rtree_rstar_tag {};
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RSTAR_TAGS_HPP
|
||||
111
include/boost/geometry/extensions/index/rtree/rtree.hpp
Normal file
111
include/boost/geometry/extensions/index/rtree/rtree.hpp
Normal file
@@ -0,0 +1,111 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.Index - R-tree implementation
|
||||
//
|
||||
// Copyright 2008 Federico J. Fernandez.
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_RTREE_RTREE_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_HPP
|
||||
|
||||
#include <boost/geometry/extensions/index/default_parameter.hpp>
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/filters.hpp>
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/visitors/rtree_find.hpp>
|
||||
#include <boost/geometry/extensions/index/rtree/visitors/rtree_delete.hpp>
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/rstar/rstar.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
// TODO: awulkiew - min and max elems as template parameters?
|
||||
|
||||
template <
|
||||
typename Value,
|
||||
typename Translator = default_parameter,
|
||||
typename Box = default_parameter,
|
||||
typename Tag = rtree_rstar_tag
|
||||
>
|
||||
class rtree
|
||||
{
|
||||
public:
|
||||
typedef Value value_type;
|
||||
typedef typename detail::default_translator_type<Value, Translator>::type translator_type;
|
||||
typedef typename detail::default_box_type<typename translator_type::indexable_type, Box>::type box_type;
|
||||
|
||||
typedef typename detail::rtree_node<Value, box_type, rtree_rstar_tag>::type node;
|
||||
typedef typename detail::rtree_internal_node<Value, box_type, rtree_rstar_tag>::type internal_node;
|
||||
typedef typename detail::rtree_leaf<Value, box_type, rtree_rstar_tag>::type leaf;
|
||||
|
||||
inline explicit rtree(size_t max_elems_per_node = 4, size_t min_elems_per_node = 2, translator_type const& translator = translator_type())
|
||||
: m_values_count(0)
|
||||
, m_max_elems_per_node(max_elems_per_node)
|
||||
, m_min_elems_per_node(min_elems_per_node)
|
||||
, m_root(0)
|
||||
, m_translator(translator)
|
||||
{
|
||||
if ( min_elems_per_node < 2 )
|
||||
min_elems_per_node = 2;
|
||||
|
||||
// TODO: awulkiew - reconsider following assert
|
||||
assert(2 * m_min_elems_per_node <= m_max_elems_per_node);
|
||||
|
||||
m_root = detail::rtree_create_node(leaf());
|
||||
}
|
||||
|
||||
~rtree()
|
||||
{
|
||||
visitors::rtree_delete<Value, translator_type, box_type, Tag> del_v;
|
||||
boost::apply_visitor(del_v, *m_root);
|
||||
}
|
||||
|
||||
template <typename Geometry>
|
||||
inline std::vector<Value> find(Geometry const& geom) const
|
||||
{
|
||||
visitors::rtree_find<Value, translator_type, box_type, Tag, Geometry> find_v(geom, m_translator);
|
||||
boost::apply_visitor(find_v, *m_root);
|
||||
return find_v.result;
|
||||
}
|
||||
|
||||
void insert(Value const& value)
|
||||
{
|
||||
visitors::rtree_insert<Value, translator_type, box_type, Tag>
|
||||
insert_v(m_root, value, m_min_elems_per_node, m_max_elems_per_node, m_translator);
|
||||
|
||||
boost::apply_visitor(insert_v, *m_root);
|
||||
|
||||
++m_values_count;
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
void apply_visitor(Visitor & visitor) const
|
||||
{
|
||||
boost::apply_visitor(visitor, *m_root);
|
||||
}
|
||||
|
||||
translator_type const& get_translator() const
|
||||
{
|
||||
return m_translator;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t m_values_count;
|
||||
size_t m_max_elems_per_node;
|
||||
size_t m_min_elems_per_node;
|
||||
node *m_root;
|
||||
translator_type m_translator;
|
||||
};
|
||||
|
||||
template <typename Value, typename Translator, typename Box, typename Tag>
|
||||
void insert(rtree<Value, Translator, Box, Tag> & tree, Value const& v)
|
||||
{
|
||||
tree.insert(v);
|
||||
}
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RSTREE_RSTREE_HPP
|
||||
196
include/boost/geometry/extensions/index/rtree/rtree_node.hpp
Normal file
196
include/boost/geometry/extensions/index/rtree/rtree_node.hpp
Normal file
@@ -0,0 +1,196 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.Index - R-tree details
|
||||
//
|
||||
// Copyright 2008 Federico J. Fernandez.
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_RTREE_DEFAULT_NODE_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_DEFAULT_NODE_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Value, typename Box, typename Tag>
|
||||
struct rtree_node;
|
||||
|
||||
// nodes default types
|
||||
|
||||
template <typename Value, typename Box, typename Tag>
|
||||
struct rtree_internal_node_def
|
||||
{
|
||||
typedef std::vector<
|
||||
std::pair<
|
||||
Box,
|
||||
typename rtree_node<Value, Box, Tag>::type *
|
||||
>
|
||||
> children_type;
|
||||
|
||||
children_type children;
|
||||
};
|
||||
|
||||
template <typename Value, typename Box, typename Tag>
|
||||
struct rtree_leaf_def
|
||||
{
|
||||
typedef std::vector<Value> values_type;
|
||||
values_type values;
|
||||
};
|
||||
|
||||
// nodes traits
|
||||
|
||||
template <typename Value, typename Box, typename Tag>
|
||||
struct rtree_node
|
||||
{
|
||||
typedef boost::variant<
|
||||
rtree_leaf_def<Value, Box, Tag>,
|
||||
rtree_internal_node_def<Value, Box, Tag>
|
||||
> type;
|
||||
};
|
||||
|
||||
template <typename Value, typename Box, typename Tag>
|
||||
struct rtree_internal_node
|
||||
{
|
||||
typedef rtree_internal_node_def<Value, Box, Tag> type;
|
||||
};
|
||||
|
||||
template <typename Value, typename Box, typename Tag>
|
||||
struct rtree_leaf
|
||||
{
|
||||
typedef rtree_leaf_def<Value, Box, Tag> type;
|
||||
};
|
||||
|
||||
// nodes elements extractor
|
||||
|
||||
template <typename Node>
|
||||
struct rtree_elements_type
|
||||
{
|
||||
typedef typename Node::elements_type type;
|
||||
};
|
||||
|
||||
template <typename Value, typename Box, typename Tag>
|
||||
struct rtree_elements_type< rtree_internal_node_def<Value, Box, Tag> >
|
||||
{
|
||||
typedef typename rtree_internal_node_def<Value, Box, Tag>::children_type type;
|
||||
};
|
||||
|
||||
template <typename Value, typename Box, typename Tag>
|
||||
struct rtree_elements_type< rtree_leaf_def<Value, Box, Tag> >
|
||||
{
|
||||
typedef typename rtree_leaf_def<Value, Box, Tag>::values_type type;
|
||||
};
|
||||
|
||||
template <typename Node>
|
||||
typename rtree_elements_type<Node>::type & get_elements(Node & n)
|
||||
{
|
||||
return n.elements;
|
||||
}
|
||||
|
||||
template <typename Value, typename Box, typename Tag>
|
||||
typename rtree_internal_node_def<Value, Box, Tag>::children_type &
|
||||
get_elements(rtree_internal_node_def<Value, Box, Tag> & n)
|
||||
{
|
||||
return n.children;
|
||||
}
|
||||
|
||||
template <typename Value, typename Box, typename Tag>
|
||||
typename rtree_leaf_def<Value, Box, Tag>::values_type &
|
||||
get_elements(rtree_leaf_def<Value, Box, Tag> & n)
|
||||
{
|
||||
return n.values;
|
||||
}
|
||||
|
||||
// uniform indexable type for child node element's box and value's indexable
|
||||
|
||||
template <typename Value, typename Translator>
|
||||
struct rtree_element_indexable_type
|
||||
{
|
||||
typedef typename Translator::indexable_type type;
|
||||
};
|
||||
|
||||
template <typename Value, typename Box, typename Tag, typename Translator>
|
||||
struct rtree_element_indexable_type<
|
||||
std::pair<
|
||||
Box,
|
||||
boost::variant<
|
||||
rtree_leaf_def<Value, Box, Tag>,
|
||||
rtree_internal_node_def<Value, Box, Tag>
|
||||
> *
|
||||
>,
|
||||
Translator
|
||||
>
|
||||
{
|
||||
typedef Box type;
|
||||
};
|
||||
|
||||
// uniform indexable getter for child node element's box and value's indexable
|
||||
|
||||
template <typename Value, typename Box, typename Tag, typename Translator>
|
||||
Box const&
|
||||
rtree_element_indexable(
|
||||
std::pair<
|
||||
Box,
|
||||
boost::variant<
|
||||
rtree_leaf_def<Value, Box, Tag>,
|
||||
rtree_internal_node_def<Value, Box, Tag>
|
||||
> *
|
||||
> const& el,
|
||||
Translator const&)
|
||||
{
|
||||
return el.first;
|
||||
}
|
||||
|
||||
template <typename Value, typename Translator>
|
||||
typename Translator::indexable_type const&
|
||||
rtree_element_indexable(Value const& el, Translator const& tr)
|
||||
{
|
||||
return tr(el);
|
||||
};
|
||||
|
||||
// create leaf node
|
||||
|
||||
template <typename Value, typename Box, typename Tag>
|
||||
typename rtree_node<Value, Box, Tag>::type *
|
||||
rtree_create_node(rtree_leaf_def<Value, Box, Tag> const& l)
|
||||
{
|
||||
typedef typename rtree_node<Value, Box, Tag>::type node;
|
||||
node * n = new node();
|
||||
*n = l;
|
||||
return n;
|
||||
}
|
||||
|
||||
// create internal node
|
||||
|
||||
template <typename Value, typename Box, typename Tag>
|
||||
typename rtree_node<Value, Box, Tag>::type *
|
||||
rtree_create_node(rtree_internal_node_def<Value, Box, Tag> const& in)
|
||||
{
|
||||
typedef typename rtree_node<Value, Box, Tag>::type node;
|
||||
node * n = new node();
|
||||
*n = in;
|
||||
return n;
|
||||
}
|
||||
|
||||
// default node
|
||||
|
||||
template <typename Value, typename Box, typename Tag>
|
||||
void rtree_delete_node(
|
||||
boost::variant<
|
||||
rtree_leaf_def<Value, Box, Tag>,
|
||||
rtree_internal_node_def<Value, Box, Tag>
|
||||
> * n)
|
||||
{
|
||||
delete n;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_DEFAULT_NODE_HPP
|
||||
@@ -0,0 +1,182 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.Index - R-tree GL-draw visitor
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_RTREE_VISITORS_GL_DRAW_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_GL_DRAW_HPP
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/rtree_node.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
namespace visitors {
|
||||
|
||||
namespace dispatch {
|
||||
|
||||
template <typename Point, size_t Dimension>
|
||||
struct rtree_gl_draw_point
|
||||
{};
|
||||
|
||||
template <typename Point>
|
||||
struct rtree_gl_draw_point<Point, 2>
|
||||
{
|
||||
static inline void apply(Point const& p)
|
||||
{
|
||||
glBegin(GL_POINT);
|
||||
glVertex2f(geometry::get<0>(p), geometry::get<1>(p));
|
||||
glEnd();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box, size_t Dimension>
|
||||
struct rtree_gl_draw_box
|
||||
{};
|
||||
|
||||
template <typename Box>
|
||||
struct rtree_gl_draw_box<Box, 2>
|
||||
{
|
||||
static inline void apply(Box const& b)
|
||||
{
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(geometry::get<min_corner, 0>(b), geometry::get<min_corner, 1>(b));
|
||||
glVertex2f(geometry::get<max_corner, 0>(b), geometry::get<min_corner, 1>(b));
|
||||
glVertex2f(geometry::get<max_corner, 0>(b), geometry::get<max_corner, 1>(b));
|
||||
glVertex2f(geometry::get<min_corner, 0>(b), geometry::get<max_corner, 1>(b));
|
||||
glEnd();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Indexable, typename Tag>
|
||||
struct rtree_gl_draw_indexable
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Indexable>
|
||||
struct rtree_gl_draw_indexable<Indexable, box_tag>
|
||||
{
|
||||
typedef typename geometry::traits::point_type<Indexable>::type point_type;
|
||||
static const size_t dimension = geometry::traits::dimension<point_type>::value;
|
||||
|
||||
static inline void apply(Indexable const& i)
|
||||
{
|
||||
rtree_gl_draw_box<Indexable, dimension>::apply(i);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Indexable>
|
||||
struct rtree_gl_draw_indexable<Indexable, point_tag>
|
||||
{
|
||||
static const size_t dimension = geometry::traits::dimension<Indexable>::value;
|
||||
|
||||
static inline void apply(std::ostream &os, Indexable const& i)
|
||||
{
|
||||
rtree_gl_draw_point<Indexable, dimension>::apply(i);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Indexable>
|
||||
inline void rtree_gl_draw_indexable(Indexable const& i)
|
||||
{
|
||||
dispatch::rtree_gl_draw_indexable<
|
||||
Indexable,
|
||||
typename geometry::traits::tag<Indexable>::type
|
||||
>::apply(i);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Value, typename Translator, typename Box, typename Tag>
|
||||
struct rtree_gl_draw : public boost::static_visitor<>
|
||||
{
|
||||
typedef typename index::detail::rtree_internal_node<Value, Box, Tag>::type internal_node;
|
||||
typedef typename index::detail::rtree_leaf<Value, Box, Tag>::type leaf;
|
||||
|
||||
inline rtree_gl_draw(Translator const& t)
|
||||
: tr(t), level(0)
|
||||
{}
|
||||
|
||||
inline void operator()(internal_node const& n)
|
||||
{
|
||||
typedef typename internal_node::children_type children_type;
|
||||
|
||||
if ( level == 0 )
|
||||
glColor3f(1.0f, 0.0f, 0.0f);
|
||||
else if ( level == 1 )
|
||||
glColor3f(0.0f, 1.0f, 0.0f);
|
||||
else if ( level == 2 )
|
||||
glColor3f(0.0f, 0.0f, 1.0f);
|
||||
else if ( level == 3 )
|
||||
glColor3f(1.0f, 1.0f, 0.0f);
|
||||
else if ( level == 4 )
|
||||
glColor3f(1.0f, 0.0f, 1.0f);
|
||||
else if ( level == 5 )
|
||||
glColor3f(0.0f, 1.0f, 1.0f);
|
||||
else
|
||||
glColor3f(0.5f, 0.5f, 0.5f);
|
||||
|
||||
for (typename children_type::const_iterator it = n.children.begin();
|
||||
it != n.children.end(); ++it)
|
||||
{
|
||||
detail::rtree_gl_draw_indexable(it->first);
|
||||
}
|
||||
|
||||
size_t level_backup = level;
|
||||
++level;
|
||||
|
||||
for (typename children_type::const_iterator it = n.children.begin();
|
||||
it != n.children.end(); ++it)
|
||||
{
|
||||
boost::apply_visitor(*this, *it->second);
|
||||
}
|
||||
|
||||
level = level_backup;
|
||||
}
|
||||
|
||||
inline void operator()(leaf const& n)
|
||||
{
|
||||
typedef typename leaf::values_type values_type;
|
||||
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
|
||||
for (typename values_type::const_iterator it = n.values.begin();
|
||||
it != n.values.end(); ++it)
|
||||
{
|
||||
detail::rtree_gl_draw_indexable(tr(*it));
|
||||
}
|
||||
}
|
||||
|
||||
Translator const& tr;
|
||||
|
||||
size_t level;
|
||||
};
|
||||
|
||||
} // namespace visitors
|
||||
|
||||
template <typename Value, typename Translator, typename Box, typename Tag>
|
||||
void gl_draw(rtree<Value, Translator, Box, Tag> const& tree)
|
||||
{
|
||||
typedef typename rtree<Value, Translator, Box, Tag>::translator_type translator_type;
|
||||
typedef typename rtree<Value, Translator, Box, Tag>::box_type box_type;
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
visitors::rtree_gl_draw<Value, translator_type, box_type, Tag> gl_draw_v(tree.get_translator());
|
||||
tree.apply_visitor(gl_draw_v);
|
||||
|
||||
glFlush();
|
||||
}
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_GL_DRAW_HPP
|
||||
207
include/boost/geometry/extensions/index/rtree/visitors/print.hpp
Normal file
207
include/boost/geometry/extensions/index/rtree/visitors/print.hpp
Normal file
@@ -0,0 +1,207 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.Index - R-tree printing visitor
|
||||
//
|
||||
// Copyright 2008 Federico J. Fernandez.
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_RTREE_VISITORS_PRINT_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_PRINT_HPP
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/rtree_node.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
namespace visitors {
|
||||
|
||||
namespace dispatch {
|
||||
|
||||
template <typename Point, size_t Dimension>
|
||||
struct rtree_print_point
|
||||
{
|
||||
BOOST_STATIC_ASSERT(0 < Dimension);
|
||||
|
||||
static inline void apply(std::ostream & os, Point const& p)
|
||||
{
|
||||
rtree_print_point<Point, Dimension - 1>::apply(os, p);
|
||||
|
||||
os << ", " << geometry::get<Dimension - 1>(p);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point>
|
||||
struct rtree_print_point<Point, 1>
|
||||
{
|
||||
static inline void apply(std::ostream & os, Point const& p)
|
||||
{
|
||||
os << geometry::get<0>(p);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box, size_t Corner, size_t Dimension>
|
||||
struct rtree_print_corner
|
||||
{
|
||||
BOOST_STATIC_ASSERT(0 < Dimension);
|
||||
|
||||
static inline void apply(std::ostream & os, Box const& b)
|
||||
{
|
||||
rtree_print_corner<Box, Corner, Dimension - 1>::apply(os, b);
|
||||
|
||||
os << ", " << geometry::get<Corner, Dimension - 1>(b);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box, size_t Corner>
|
||||
struct rtree_print_corner<Box, Corner, 1>
|
||||
{
|
||||
static inline void apply(std::ostream & os, Box const& b)
|
||||
{
|
||||
os << geometry::get<Corner, 0>(b);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Indexable, typename Tag>
|
||||
struct rtree_print_indexable
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Indexable>
|
||||
struct rtree_print_indexable<Indexable, box_tag>
|
||||
{
|
||||
typedef typename geometry::traits::point_type<Indexable>::type point_type;
|
||||
static const size_t dimension = geometry::traits::dimension<point_type>::value;
|
||||
|
||||
static inline void apply(std::ostream &os, Indexable const& i)
|
||||
{
|
||||
os << '(';
|
||||
rtree_print_corner<Indexable, min_corner, dimension>::apply(os, i);
|
||||
os << ")x(";
|
||||
rtree_print_corner<Indexable, max_corner, dimension>::apply(os, i);
|
||||
os << ')';
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Indexable>
|
||||
struct rtree_print_indexable<Indexable, point_tag>
|
||||
{
|
||||
static const size_t dimension = geometry::traits::dimension<Indexable>::value;
|
||||
|
||||
static inline void apply(std::ostream &os, Indexable const& i)
|
||||
{
|
||||
os << '(';
|
||||
rtree_print_point<Indexable, dimension>::apply(os, i);
|
||||
os << ')';
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Indexable>
|
||||
inline void rtree_print_indexable(std::ostream & os, Indexable const& i)
|
||||
{
|
||||
dispatch::rtree_print_indexable<
|
||||
Indexable,
|
||||
typename geometry::traits::tag<Indexable>::type
|
||||
>::apply(os, i);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Value, typename Translator, typename Box, typename Tag>
|
||||
struct rtree_print : public boost::static_visitor<>
|
||||
{
|
||||
typedef typename index::detail::rtree_internal_node<Value, Box, Tag>::type internal_node;
|
||||
typedef typename index::detail::rtree_leaf<Value, Box, Tag>::type leaf;
|
||||
|
||||
inline rtree_print(std::ostream & o, Translator const& t)
|
||||
: os(o), tr(t), level(0)
|
||||
{}
|
||||
|
||||
inline void operator()(internal_node const& n)
|
||||
{
|
||||
typedef typename internal_node::children_type children_type;
|
||||
|
||||
os << " --> Node --------" << std::endl;
|
||||
os << " Address: " << this << std::endl;
|
||||
os << " Level: " << level << std::endl;
|
||||
os << " Children: " << n.children.size() << std::endl;
|
||||
os << " | ";
|
||||
|
||||
for (typename children_type::const_iterator it = n.children.begin();
|
||||
it != n.children.end(); ++it)
|
||||
{
|
||||
detail::rtree_print_indexable(os, it->first);
|
||||
os << " | ";
|
||||
}
|
||||
os << std::endl;
|
||||
os << " --< Node --------" << std::endl;
|
||||
|
||||
os << " Children: " << std::endl;
|
||||
|
||||
size_t level_backup = level;
|
||||
++level;
|
||||
|
||||
for (typename children_type::const_iterator it = n.children.begin();
|
||||
it != n.children.end(); ++it)
|
||||
{
|
||||
boost::apply_visitor(*this, *it->second);
|
||||
}
|
||||
|
||||
level = level_backup;
|
||||
}
|
||||
|
||||
inline void operator()(leaf const& n)
|
||||
{
|
||||
typedef typename leaf::values_type values_type;
|
||||
|
||||
os << "\t" << " --> Leaf --------" << std::endl;
|
||||
os << "\t" << " Values: " << n.values.size() << std::endl;
|
||||
for (typename values_type::const_iterator it = n.values.begin();
|
||||
it != n.values.end(); ++it)
|
||||
{
|
||||
os << "\t" << " | ";
|
||||
detail::rtree_print_indexable(os, tr(*it));
|
||||
os << " | " << std::endl;;
|
||||
}
|
||||
os << "\t" << " --< Leaf --------" << std::endl;
|
||||
|
||||
}
|
||||
|
||||
std::ostream & os;
|
||||
Translator const& tr;
|
||||
|
||||
size_t level;
|
||||
};
|
||||
|
||||
} // namespace visitors
|
||||
|
||||
template <typename Value, typename Translator, typename Box, typename Tag>
|
||||
std::ostream & print(rtree<Value, Translator, Box, Tag> const& tree, std::ostream & os = std::cout)
|
||||
{
|
||||
typedef typename rtree<Value, Translator, Box, Tag>::translator_type translator_type;
|
||||
typedef typename rtree<Value, Translator, Box, Tag>::box_type box_type;
|
||||
visitors::rtree_print<Value, translator_type, box_type, Tag> print_v(os, tree.get_translator());
|
||||
tree.apply_visitor(print_v);
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename Value, typename Translator, typename Box, typename Tag>
|
||||
std::ostream & operator<<(std::ostream & os, rtree<Value, Translator, Box, Tag> const& tree)
|
||||
{
|
||||
typedef typename rtree<Value, Translator, Box, Tag>::translator_type translator_type;
|
||||
typedef typename rtree<Value, Translator, Box, Tag>::box_type box_type;
|
||||
visitors::rtree_print<Value, translator_type, box_type, Tag> print_v(os, tree.get_translator());
|
||||
tree.apply_visitor(print_v);
|
||||
return os;
|
||||
}
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_PRINT_HPP
|
||||
@@ -0,0 +1,47 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.Index - R-tree delete visitor
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_DELETE_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_DELETE_HPP
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/rtree_node.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
namespace visitors {
|
||||
|
||||
template <typename Value, typename Translator, typename Box, typename Tag>
|
||||
struct rtree_delete : public boost::static_visitor<>
|
||||
{
|
||||
typedef typename index::detail::rtree_internal_node<Value, Box, Tag>::type internal_node;
|
||||
typedef typename index::detail::rtree_leaf<Value, Box, Tag>::type leaf;
|
||||
|
||||
inline void operator()(internal_node & n) const
|
||||
{
|
||||
typedef typename internal_node::children_type children_type;
|
||||
|
||||
for (typename children_type::iterator it = n.children.begin();
|
||||
it != n.children.end(); ++it)
|
||||
{
|
||||
boost::apply_visitor(*this, *it->second);
|
||||
|
||||
index::detail::rtree_delete_node(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
inline void operator()(leaf & n) const
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace visitors
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_DELETE_HPP
|
||||
@@ -0,0 +1,66 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.Index - R-tree find
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_FIND_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_FIND_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/intersects.hpp>
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/rtree_node.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
namespace visitors {
|
||||
|
||||
// rtree spatial query visitor
|
||||
|
||||
template <typename Value, typename Translator, typename Box, typename Tag, typename Geometry>
|
||||
struct rtree_find : public boost::static_visitor<>
|
||||
{
|
||||
typedef typename index::detail::rtree_internal_node<Value, Box, Tag>::type internal_node;
|
||||
typedef typename index::detail::rtree_leaf<Value, Box, Tag>::type leaf;
|
||||
|
||||
inline rtree_find(Geometry const& g, Translator const& t)
|
||||
: geom(g), tr(t)
|
||||
{}
|
||||
|
||||
inline void operator()(internal_node const& n)
|
||||
{
|
||||
typedef typename internal_node::children_type children_type;
|
||||
|
||||
for (typename children_type::const_iterator it = n.children.begin();
|
||||
it != n.children.end(); ++it)
|
||||
{
|
||||
if ( geometry::intersects(it->first, geom) )
|
||||
boost::apply_visitor(*this, *it->second);
|
||||
}
|
||||
}
|
||||
|
||||
inline void operator()(leaf const& n)
|
||||
{
|
||||
typedef typename leaf::values_type values_type;
|
||||
|
||||
for (typename values_type::const_iterator it = n.values.begin();
|
||||
it != n.values.end(); ++it)
|
||||
{
|
||||
if ( geometry::intersects(tr(*it), geom) )
|
||||
result.push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
Geometry const& geom;
|
||||
Translator const& tr;
|
||||
std::vector<Value> result;
|
||||
};
|
||||
|
||||
} // namespace visitors
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_FIND_HPP
|
||||
@@ -0,0 +1,29 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.Index - R-tree details
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_INSERT_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_INSERT_HPP
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/rtree_node.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
namespace visitors {
|
||||
|
||||
template <typename Value, typename Translator, typename Box, typename Tag>
|
||||
struct rtree_insert
|
||||
{
|
||||
// not implemented here
|
||||
};
|
||||
|
||||
} // namespace visitors
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_INSERT_HPP
|
||||
@@ -0,0 +1,40 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.Index - R-tree is leaf visitor
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_IS_LEAF_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_IS_LEAF_HPP
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/rtree_node.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
namespace visitors {
|
||||
|
||||
template <typename Value, typename Box, typename Tag>
|
||||
struct rtree_is_leaf : public boost::static_visitor<bool>
|
||||
{
|
||||
typedef typename index::detail::rtree_internal_node<Value, Box, Tag>::type internal_node;
|
||||
typedef typename index::detail::rtree_leaf<Value, Box, Tag>::type leaf;
|
||||
|
||||
inline bool operator()(internal_node const&) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool operator()(leaf const&) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace visitors
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_IS_LEAF_HPP
|
||||
@@ -0,0 +1,29 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.Index - R-tree remove
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_REMOVE_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_REMOVE_HPP
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/rtree_node.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
namespace visitors {
|
||||
|
||||
template <typename Value, typename Translator, typename Box, typename Tag>
|
||||
struct rtree_remove
|
||||
{
|
||||
// not implemented here
|
||||
};
|
||||
|
||||
} // namespace visitors
|
||||
|
||||
}}} // namespace boost::geometry::index
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_REMOVE_HPP
|
||||
103
include/boost/geometry/extensions/index/translator/def.hpp
Normal file
103
include/boost/geometry/extensions/index/translator/def.hpp
Normal file
@@ -0,0 +1,103 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.SpatialIndex - default value to bounding object translation
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_TRANSLATOR_DEF_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_TRANSLATOR_DEF_HPP
|
||||
|
||||
#include <boost/geometry/extensions/index/translator/helpers.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index { namespace translator {
|
||||
|
||||
namespace dispatch {
|
||||
|
||||
// Distinguish between def<Geometry>, def<Iterator> and def<SmartPtr>
|
||||
|
||||
// Geometry
|
||||
template <typename Value, bool IsIterator, bool IsSmartPtr>
|
||||
struct def
|
||||
{
|
||||
typedef typename detail::extract_indexable<Value>::type indexable_type;
|
||||
|
||||
indexable_type const& operator()(Value const& v) const
|
||||
{
|
||||
return detail::extract_indexable<Value>::get(v);
|
||||
}
|
||||
|
||||
/*bool equals(Value const& v1, Value const& v2) const
|
||||
{
|
||||
return detail::equals<Value>::apply(v1, v2);
|
||||
}*/
|
||||
};
|
||||
|
||||
// Iterator
|
||||
template <typename Value, bool IsSmartPtr>
|
||||
struct def<Value, true, IsSmartPtr>
|
||||
{
|
||||
typedef typename detail::extract_indexable<typename Value::value_type>::type indexable_type;
|
||||
|
||||
indexable_type const& operator()(Value const& v) const
|
||||
{
|
||||
return detail::extract_indexable<typename Value::value_type>::get(*v);
|
||||
}
|
||||
|
||||
/*bool equals(Value const& v1, Value const& v2) const
|
||||
{
|
||||
return v1 == v2;
|
||||
}*/
|
||||
};
|
||||
|
||||
// SmartPtr
|
||||
template <typename Value>
|
||||
struct def<Value, false, true>
|
||||
{
|
||||
typedef typename detail::extract_indexable<typename Value::element_type>::type indexable_type;
|
||||
|
||||
indexable_type const& operator()(Value const& v) const
|
||||
{
|
||||
return detail::extract_indexable<typename Value::element_type>::get(*v);
|
||||
}
|
||||
|
||||
/*bool equals(Value const& v1, Value const& v2) const
|
||||
{
|
||||
return v1 == v2;
|
||||
}*/
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
|
||||
template <typename Value>
|
||||
struct def
|
||||
: public dispatch::def
|
||||
<
|
||||
Value,
|
||||
detail::is_iterator<Value>::value,
|
||||
detail::is_smart_ptr<Value>::value
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Value>
|
||||
struct def<Value*>
|
||||
{
|
||||
typedef typename detail::extract_indexable<Value>::type indexable_type;
|
||||
|
||||
indexable_type const& operator()(const Value *v) const
|
||||
{
|
||||
return detail::extract_indexable<Value>::get(*v);
|
||||
}
|
||||
|
||||
/*bool equals(const Value* v1, const Value* v2) const
|
||||
{
|
||||
return v1 == v2;
|
||||
}*/
|
||||
};
|
||||
|
||||
}}}} // namespace boost::geometry::index::translator
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_TRANSLATOR_DEF_HPP
|
||||
192
include/boost/geometry/extensions/index/translator/helpers.hpp
Normal file
192
include/boost/geometry/extensions/index/translator/helpers.hpp
Normal file
@@ -0,0 +1,192 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.SpatialIndex - translators helper functions
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_TRANSLATOR_HELPERS_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_TRANSLATOR_HELPERS_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
|
||||
#include <boost/geometry/extensions/index/indexable.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index { namespace translator {
|
||||
|
||||
namespace dispatch {
|
||||
|
||||
// Extract object from std::pair by non-void tag
|
||||
|
||||
template <typename Pair, typename FirstTag, typename SecondTag>
|
||||
struct choose_pair_element
|
||||
{
|
||||
typedef typename Pair::first_type type;
|
||||
static type const& get(Pair const& p) { return p.first; }
|
||||
};
|
||||
|
||||
template <typename Pair, typename FirstTag>
|
||||
struct choose_pair_element<Pair, FirstTag, void>
|
||||
{
|
||||
typedef typename Pair::first_type type;
|
||||
static type const& get(Pair const& p) { return p.first; }
|
||||
};
|
||||
|
||||
template <typename Pair, typename Second>
|
||||
struct choose_pair_element<Pair, void, Second>
|
||||
{
|
||||
typedef typename Pair::second_type type;
|
||||
static type const& get(Pair const& p) { return p.second; }
|
||||
};
|
||||
|
||||
template <typename Pair>
|
||||
struct choose_pair_element<Pair, void, void>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Geometry>
|
||||
struct indexable_not_found_error
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
template <>
|
||||
struct indexable_not_found_error<void>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
// Extract indexable
|
||||
|
||||
template <typename Value>
|
||||
struct extract_indexable
|
||||
{
|
||||
typedef Value type;
|
||||
|
||||
BOOST_STATIC_ASSERT(!indexable_not_found_error<type>::value);
|
||||
|
||||
static type const& get(Value const& v) { return v; }
|
||||
};
|
||||
|
||||
template <typename First, typename Second>
|
||||
struct extract_indexable< std::pair<First, Second> >
|
||||
{
|
||||
typedef typename dispatch::choose_pair_element<
|
||||
std::pair<First, Second>,
|
||||
typename traits::indexable_type<First>::type,
|
||||
typename traits::indexable_type<Second>::type
|
||||
> cp;
|
||||
|
||||
typedef typename cp::type type;
|
||||
|
||||
BOOST_STATIC_ASSERT(!indexable_not_found_error<type>::value);
|
||||
|
||||
static type const& get(std::pair<First, Second> const& v)
|
||||
{
|
||||
return cp::get(v);
|
||||
}
|
||||
};
|
||||
|
||||
// Recognize iterators and smart pointers
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator_category)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(difference_type)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(pointer)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(reference)
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type)
|
||||
|
||||
// TODO
|
||||
// use has_operator_xxx in the future
|
||||
|
||||
template <typename T>
|
||||
struct is_iterator
|
||||
{
|
||||
static const bool value = boost::mpl::and_
|
||||
<
|
||||
has_iterator_category<T>,
|
||||
has_value_type<T>,
|
||||
has_difference_type<T>,
|
||||
has_pointer<T>,
|
||||
has_reference<T>
|
||||
>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_smart_ptr
|
||||
{
|
||||
static const bool value = has_element_type<T>::value;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//namespace dispatch {
|
||||
//
|
||||
//template <typename Geometry, typename Tag>
|
||||
//struct equals
|
||||
//{
|
||||
// static bool apply(Geometry const& g1, Geometry const& g2)
|
||||
// {
|
||||
// return geometry::equals(g1, g2);
|
||||
// }
|
||||
//};
|
||||
//
|
||||
//template <typename T>
|
||||
//struct equals<T, void>
|
||||
//{
|
||||
// static bool apply(T const& v1, T const& v2)
|
||||
// {
|
||||
// return v1 == v2;
|
||||
// }
|
||||
//};
|
||||
//
|
||||
//} // namespace dispatch
|
||||
//
|
||||
//namespace detail {
|
||||
//
|
||||
//template <typename Geometry>
|
||||
//struct equals
|
||||
//{
|
||||
// static bool apply(Geometry const& g1, Geometry const& g2)
|
||||
// {
|
||||
// return geometry::equals(g1, g2);
|
||||
// }
|
||||
//};
|
||||
//
|
||||
//template <typename First, typename Second>
|
||||
//struct equals< std::pair<First, Second> >
|
||||
//{
|
||||
// static bool apply(std::pair<First, Second> const& p1, std::pair<First, Second> const& p2)
|
||||
// {
|
||||
// return
|
||||
// dispatch::equals<
|
||||
// First,
|
||||
// typename traits::tag<First>::type
|
||||
// >::apply(p1.first, p2.first)
|
||||
// &&
|
||||
// dispatch::equals<
|
||||
// Second,
|
||||
// typename traits::tag<Second>::type
|
||||
// >::apply(p1.second, p2.second);
|
||||
// }
|
||||
//};
|
||||
//
|
||||
//} // namespace detail
|
||||
|
||||
|
||||
|
||||
}}}} // namespace boost::geometry::index::translator
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_TRANSLATOR_HELPERS_HPP
|
||||
43
include/boost/geometry/extensions/index/translator/index.hpp
Normal file
43
include/boost/geometry/extensions/index/translator/index.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Boost.SpatialIndex - container index value to bounding object translation
|
||||
//
|
||||
// Copyright 2011 Adam Wulkiewicz.
|
||||
// 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_EXTENSIONS_INDEX_TRANSLATOR_INDEX_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_TRANSLATOR_INDEX_HPP
|
||||
|
||||
#include <boost/geometry/extensions/index/translator/helpers.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index { namespace translator {
|
||||
|
||||
template <typename Container>
|
||||
class index
|
||||
{
|
||||
public:
|
||||
typedef typename detail::extract_indexable
|
||||
<typename Container::value_type>::type indexable_type;
|
||||
|
||||
explicit index(Container const& c) : m_c(c) {}
|
||||
|
||||
indexable_type const& operator()(size_t i) const
|
||||
{
|
||||
return detail::extract_indexable
|
||||
<typename Container::value_type>::get(m_c[i]);
|
||||
}
|
||||
|
||||
/*bool equals(size_t i1, size_t i2) const
|
||||
{
|
||||
return i1 == i2;
|
||||
}*/
|
||||
|
||||
private:
|
||||
Container const& m_c;
|
||||
};
|
||||
|
||||
}}}} // namespace boost::geometry::index::translator
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_TRANSLATOR_INDEX_HPP
|
||||
20
tests/TODO.txt
Normal file
20
tests/TODO.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
// TODO
|
||||
// wewnetrzny typ pudelek zmienic na geometry::box<geometry::point>
|
||||
// do kopiowania pudelek uzytkownik -> internal uzyc specjlnej funkcji
|
||||
// przydalaby sie inna struktura wezlow - w tej powielane sa dane
|
||||
// node <- internal_node, node <- leaf_node
|
||||
// traktowanie liscia jako wezla wewnetrznego tez jest bez sensu (nie widze dobrej sytuacji)
|
||||
|
||||
// czy translator powinien zwracac geometry::model::point czy Point
|
||||
// a jesli zalozymy ze uzytkownik przechowuje Polygon to powinien on byc przechowywany z Boxem czy nie
|
||||
// to przechowuje pair<Box, Polygon> lub jesli przechowuje Box pisze sobie nowy translator
|
||||
|
||||
// czy wewnatrz struktury powinny byc przechowywane: Box i geometry::box<Point>
|
||||
// czy geometry::box<geometry::point<traits::dimension<Point>::value>, ...>
|
||||
|
||||
// 1. box wewnatrz wezlow
|
||||
// 2. bounding object w lisciach
|
||||
|
||||
// 3. jakis automatyczny przechowywacz innych obiektow? polygon, segment
|
||||
// powinien istniec automatyczny translator obiekt -> box
|
||||
// i box/point przechowywany w lisciach razem z obiektem
|
||||
70
tests/additional_glut_vis.cpp
Normal file
70
tests/additional_glut_vis.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#include <gl/glut.h>
|
||||
#define BOOST_GEOMETRY_INDEX_RTREE_ENABLE_GL_DRAW
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/rtree.hpp>
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/visitors/gl_draw.hpp>
|
||||
|
||||
typedef boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> P;
|
||||
typedef boost::geometry::model::box<P> B;
|
||||
boost::geometry::index::rtree<B> t;
|
||||
|
||||
void render_scene(void)
|
||||
{
|
||||
boost::geometry::index::gl_draw(t);
|
||||
}
|
||||
|
||||
void resize(int w, int h)
|
||||
{
|
||||
if ( h == 0 )
|
||||
h = 1;
|
||||
|
||||
float ratio = float(w) / h;
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
glViewport(0, 0, w, h);
|
||||
|
||||
gluPerspective(45, ratio, 1, 1000);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt(
|
||||
5.0f, 5.0f, 15.0f,
|
||||
5.0f, 5.0f, -1.0f,
|
||||
0.0f, 1.0f, 0.0f);
|
||||
}
|
||||
|
||||
void mouse(int button, int state, int x, int y)
|
||||
{
|
||||
if ( state == GLUT_DOWN )
|
||||
{
|
||||
float x = ( rand() % 10000 ) / 1000.0f;
|
||||
float y = ( rand() % 10000 ) / 1000.0f;
|
||||
float w = ( rand() % 10000 ) / 100000.0f;
|
||||
float h = ( rand() % 10000 ) / 100000.0f;
|
||||
|
||||
boost::geometry::index::insert(t, B(P(x - w, y - h),P(x + w, y + h)));
|
||||
|
||||
glutPostRedisplay();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
glutInit(&argc, argv);
|
||||
glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);
|
||||
glutInitWindowPosition(100,100);
|
||||
glutInitWindowSize(800, 600);
|
||||
glutCreateWindow("Mouse click to insert new value");
|
||||
|
||||
glutDisplayFunc(render_scene);
|
||||
glutReshapeFunc(resize);
|
||||
glutMouseFunc(mouse);
|
||||
|
||||
std::cout << "Mouse click to insert new value";
|
||||
|
||||
glutMainLoop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
62
tests/additional_sizes_and_times.cpp
Normal file
62
tests/additional_sizes_and_times.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <boost/geometry/extensions/index/rtree/rtree.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/timer.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> P;
|
||||
typedef boost::geometry::model::box<P> B;
|
||||
|
||||
boost::geometry::index::rtree<B>::leaf l;
|
||||
boost::geometry::index::rtree<B>::internal_node n;
|
||||
|
||||
std::cout << "internal node size: " << sizeof(n) << '\n';
|
||||
std::cout << "leaf size: " << sizeof(l) << '\n';
|
||||
}
|
||||
|
||||
boost::timer tim;
|
||||
|
||||
{
|
||||
typedef boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> P;
|
||||
typedef boost::geometry::model::box<P> B;
|
||||
|
||||
// randomize boxes
|
||||
const size_t n = 10000;
|
||||
std::vector<B> v(n);
|
||||
for ( size_t i = 0 ; i < n ; ++i )
|
||||
{
|
||||
float x = ( rand() % 10000 ) / 1000.0f;
|
||||
float y = ( rand() % 10000 ) / 1000.0f;
|
||||
float w = ( rand() % 10000 ) / 100000.0f;
|
||||
float h = ( rand() % 10000 ) / 100000.0f;
|
||||
v[i] = B(P(x - w, y - h),P(x + w, y + h));
|
||||
}
|
||||
|
||||
boost::geometry::index::rtree<B> t(4, 2);
|
||||
|
||||
std::cout << "inserting time test...\n";
|
||||
|
||||
tim.restart();
|
||||
|
||||
BOOST_FOREACH(B &b, v)
|
||||
{
|
||||
boost::geometry::index::insert(t, b);
|
||||
}
|
||||
|
||||
std::cout << "time: " << tim.elapsed() << "s\n";
|
||||
|
||||
std::cout << "deleting time test...\n";
|
||||
tim.restart();
|
||||
}
|
||||
std::cout << "time: " << tim.elapsed() << "s\n";
|
||||
|
||||
#ifdef _MSC_VER
|
||||
std::cin.get();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
16
tests/main.cpp
Normal file
16
tests/main.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include <tests/translators.hpp>
|
||||
#include <tests/rtree_native.hpp>
|
||||
#include <tests/rtree_filters.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
tests_translators_hpp();
|
||||
tests_rtree_native_hpp();
|
||||
tests_rtree_filters_hpp();
|
||||
|
||||
#ifdef _MSC_VER
|
||||
std::cin.get();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
54
tests/rtree_filters.hpp
Normal file
54
tests/rtree_filters.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef TESTS_RTREE_FILTERS_HPP
|
||||
#define TESTS_RTREE_FILTERS_HPP
|
||||
|
||||
#include <boost/geometry/geometry.hpp>
|
||||
#include <boost/geometry/extensions/index/rtree/rtree.hpp>
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/filters.hpp>
|
||||
#include <boost/geometry/extensions/index/filters/nearest_filter.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/range/algorithm.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
template <typename R>
|
||||
void tests_rtree_filters_hpp_print_range(R const& r)
|
||||
{
|
||||
BOOST_FOREACH(typename boost::iterator_value<typename R::const_iterator>::type const& b, r)
|
||||
{
|
||||
float min_x = b.min_corner().template get<0>();
|
||||
float min_y = b.min_corner().template get<1>();
|
||||
float max_x = b.max_corner().template get<0>();
|
||||
float max_y = b.max_corner().template get<1>();
|
||||
std::cout << "(" << min_x << ", " << min_y << ")";
|
||||
std::cout << 'x';
|
||||
std::cout << "(" << max_x << ", " << max_y << ")";
|
||||
std::cout << '\n';
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void tests_rtree_filters_hpp()
|
||||
{
|
||||
std::cout << "tests/rtree_filters.hpp\n";
|
||||
|
||||
typedef boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> P;
|
||||
typedef boost::geometry::model::box<P> B;
|
||||
|
||||
{
|
||||
boost::geometry::index::rtree<B> t(4, 2);
|
||||
boost::geometry::index::insert(t, B(P(0, 0), P(1, 1)));
|
||||
boost::geometry::index::insert(t, B(P(2, 2), P(3, 3)));
|
||||
boost::geometry::index::insert(t, B(P(4, 4), P(5, 5)));
|
||||
boost::geometry::index::insert(t, B(P(6, 6), P(7, 7)));
|
||||
boost::geometry::index::insert(t, B(P(8, 8), P(9, 9)));
|
||||
std::cout << t;
|
||||
|
||||
std::cout << "Query: (2.5, 2.5)x(4.5, 4.5)\n";
|
||||
namespace f = boost::geometry::index::filters;
|
||||
tests_rtree_filters_hpp_print_range(t | f::spatially_filtered(B(P(2.5f, 2.5f), P(4.5f, 4.5f))));
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TESTS_RTREE_FILTERS_HPP
|
||||
150
tests/rtree_native.hpp
Normal file
150
tests/rtree_native.hpp
Normal file
@@ -0,0 +1,150 @@
|
||||
#ifndef TESTS_RTREE_NATIVE_HPP
|
||||
#define TESTS_RTREE_NATIVE_HPP
|
||||
|
||||
#include <boost/geometry/geometry.hpp>
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/rtree.hpp>
|
||||
#include <boost/geometry/extensions/index/translator/index.hpp>
|
||||
|
||||
#include <boost/geometry/extensions/index/rtree/visitors/print.hpp>
|
||||
|
||||
#include <boost/range/algorithm.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <map>
|
||||
|
||||
void tests_rtree_native_hpp()
|
||||
{
|
||||
std::cout << "tests/rtree_native.hpp\n";
|
||||
|
||||
std::cout << "Boxes\n";
|
||||
{
|
||||
typedef boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> P;
|
||||
typedef boost::geometry::model::box<P> B;
|
||||
|
||||
boost::geometry::index::rtree<B> t(4, 2);
|
||||
boost::geometry::index::insert(t, B(P(0, 0), P(1, 1)));
|
||||
boost::geometry::index::insert(t, B(P(2, 2), P(3, 3)));
|
||||
boost::geometry::index::insert(t, B(P(4, 4), P(5, 5)));
|
||||
boost::geometry::index::insert(t, B(P(6, 6), P(7, 7)));
|
||||
boost::geometry::index::insert(t, B(P(8, 8), P(9, 9)));
|
||||
std::cerr << t;
|
||||
}
|
||||
|
||||
std::cout << "-------------------------------------------------\n";
|
||||
std::cout << "-------------------------------------------------\n";
|
||||
|
||||
std::cout << "Points\n";
|
||||
{
|
||||
typedef boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> P;
|
||||
typedef boost::geometry::model::box<P> B;
|
||||
|
||||
boost::geometry::index::rtree<P> t(4, 2);
|
||||
boost::geometry::index::insert(t, P(0, 0));
|
||||
boost::geometry::index::insert(t, P(2, 2));
|
||||
boost::geometry::index::insert(t, P(4, 4));
|
||||
boost::geometry::index::insert(t, P(6, 6));
|
||||
boost::geometry::index::insert(t, P(8, 8));
|
||||
std::cerr << t;
|
||||
}
|
||||
|
||||
std::cout << "-------------------------------------------------\n";
|
||||
std::cout << "-------------------------------------------------\n";
|
||||
|
||||
std::cout << "std::pair<Box, int>\n";
|
||||
{
|
||||
typedef boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> P;
|
||||
typedef boost::geometry::model::box<P> B;
|
||||
typedef std::pair<B, int> V;
|
||||
|
||||
boost::geometry::index::rtree<V> t(4, 2);
|
||||
boost::geometry::index::insert(t, V(B(P(0, 0), P(1, 1)), 0));
|
||||
boost::geometry::index::insert(t, V(B(P(2, 2), P(3, 3)), 1));
|
||||
boost::geometry::index::insert(t, V(B(P(4, 4), P(5, 5)), 2));
|
||||
boost::geometry::index::insert(t, V(B(P(6, 6), P(7, 7)), 3));
|
||||
boost::geometry::index::insert(t, V(B(P(8, 8), P(9, 9)), 4));
|
||||
std::cerr << t;
|
||||
}
|
||||
|
||||
std::cout << "-------------------------------------------------\n";
|
||||
std::cout << "-------------------------------------------------\n";
|
||||
|
||||
std::cout << "boost::shared_ptr< std::pair<Box, int> >\n";
|
||||
{
|
||||
typedef boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> P;
|
||||
typedef boost::geometry::model::box<P> B;
|
||||
|
||||
typedef boost::shared_ptr< std::pair<B, int> > V;
|
||||
|
||||
V v1( new std::pair<B, int>(B(P(0, 0), P(1, 1)), 0) );
|
||||
V v2( new std::pair<B, int>(B(P(2, 2), P(3, 3)), 1) );
|
||||
V v3( new std::pair<B, int>(B(P(4, 4), P(5, 5)), 2) );
|
||||
V v4( new std::pair<B, int>(B(P(6, 6), P(7, 7)), 3) );
|
||||
V v5( new std::pair<B, int>(B(P(8, 8), P(9, 9)), 4) );
|
||||
|
||||
boost::geometry::index::rtree<V> t(4, 2);
|
||||
boost::geometry::index::insert(t, v1);
|
||||
boost::geometry::index::insert(t, v2);
|
||||
boost::geometry::index::insert(t, v3);
|
||||
boost::geometry::index::insert(t, v4);
|
||||
boost::geometry::index::insert(t, v5);
|
||||
std::cerr << t;
|
||||
}
|
||||
|
||||
std::cout << "-------------------------------------------------\n";
|
||||
std::cout << "-------------------------------------------------\n";
|
||||
|
||||
std::cout << "std::map<int, Box>::iterator\n";
|
||||
{
|
||||
typedef boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> P;
|
||||
typedef boost::geometry::model::box<P> B;
|
||||
|
||||
typedef std::map<int, B>::iterator V;
|
||||
|
||||
std::map<int, B> m;
|
||||
m.insert(std::pair<int, B>(0, B(P(0, 0), P(1, 1))));
|
||||
m.insert(std::pair<int, B>(1, B(P(2, 2), P(3, 3))));
|
||||
m.insert(std::pair<int, B>(2, B(P(4, 4), P(5, 5))));
|
||||
m.insert(std::pair<int, B>(3, B(P(6, 6), P(7, 7))));
|
||||
m.insert(std::pair<int, B>(4, B(P(8, 8), P(9, 9))));
|
||||
|
||||
boost::geometry::index::rtree<V> t(4, 2);
|
||||
V vit = m.begin();
|
||||
boost::geometry::index::insert(t, vit++);
|
||||
boost::geometry::index::insert(t, vit++);
|
||||
boost::geometry::index::insert(t, vit++);
|
||||
boost::geometry::index::insert(t, vit++);
|
||||
boost::geometry::index::insert(t, vit);
|
||||
std::cerr << t;
|
||||
}
|
||||
|
||||
std::cout << "-------------------------------------------------\n";
|
||||
std::cout << "-------------------------------------------------\n";
|
||||
|
||||
std::cout << "size_t\n";
|
||||
{
|
||||
typedef boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> P;
|
||||
typedef boost::geometry::model::box<P> B;
|
||||
|
||||
typedef size_t V;
|
||||
typedef boost::geometry::index::translator::index<std::vector<B> > T;
|
||||
|
||||
std::vector<B> v;
|
||||
v.push_back(B(P(0, 0), P(1, 1)));
|
||||
v.push_back(B(P(2, 2), P(3, 3)));
|
||||
v.push_back(B(P(4, 4), P(5, 5)));
|
||||
v.push_back(B(P(6, 6), P(7, 7)));
|
||||
v.push_back(B(P(8, 8), P(9, 9)));
|
||||
|
||||
boost::geometry::index::rtree<V, T> t(4, 2, T(v));
|
||||
|
||||
boost::geometry::index::insert(t, 0u);
|
||||
boost::geometry::index::insert(t, 1u);
|
||||
boost::geometry::index::insert(t, 2u);
|
||||
boost::geometry::index::insert(t, 3u);
|
||||
boost::geometry::index::insert(t, 4u);
|
||||
std::cerr << t;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TESTS_RTREE_NATIVE_HPP
|
||||
72
tests/translators.hpp
Normal file
72
tests/translators.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#ifndef TESTS_TRANSLATORS_HPP
|
||||
#define TESTS_TRANSLATORS_HPP
|
||||
|
||||
#include <boost/geometry/geometry.hpp>
|
||||
#include <boost/geometry/extensions/index/rtree/rtree.hpp>
|
||||
|
||||
#include <boost/geometry/extensions/index/translator/def.hpp>
|
||||
#include <boost/geometry/extensions/index/translator/index.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
void tests_translators_hpp()
|
||||
{
|
||||
std::cout << "tests/translators.hpp\n";
|
||||
|
||||
typedef boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> P;
|
||||
typedef boost::geometry::model::box<P> B;
|
||||
typedef boost::geometry::index::rtree<B> I;
|
||||
|
||||
using namespace boost::geometry;
|
||||
|
||||
index::translator::def<P> p;
|
||||
index::translator::def<P*> pp;
|
||||
index::translator::def<std::pair<int, P>*> pip;
|
||||
index::translator::def< boost::shared_ptr<P> > sp;
|
||||
index::translator::def< std::vector<P>::iterator > ip;
|
||||
index::translator::def< std::map<int, P>::iterator > mip;
|
||||
index::translator::def< std::pair<P, size_t> > ppi;
|
||||
index::translator::def< boost::shared_ptr< std::pair<int, P> > > spip;
|
||||
index::translator::def< boost::shared_ptr< std::pair<P, int> > > sppi;
|
||||
index::translator::def< boost::scoped_ptr< std::pair<P, int> > > scppi;
|
||||
index::translator::def< boost::scoped_ptr< std::pair<int, P> > > scpip;
|
||||
|
||||
P tmp_p;
|
||||
boost::shared_ptr<P> tmp_sp(new P());
|
||||
std::vector<P> tmp_v(1);
|
||||
std::map<int, P> tmp_m;
|
||||
tmp_m.insert(std::pair<int, P>(0, P()));
|
||||
std::pair<int, P> tmp_pip;
|
||||
boost::shared_ptr< std::pair<int, P> > tmp_spip(new std::pair<int, P>(0, P()));
|
||||
boost::shared_ptr< std::pair<P, int> > tmp_sppi(new std::pair<P, int>(P(), 0));
|
||||
boost::scoped_ptr< std::pair<int, P> > tmp_scpip(new std::pair<int, P>(0, P()));
|
||||
boost::scoped_ptr< std::pair<P, int> > tmp_scppi(new std::pair<P, int>(P(), 0));
|
||||
|
||||
tmp_p = p(P());
|
||||
tmp_p = pp(&tmp_p);
|
||||
tmp_p = pip(&tmp_pip);
|
||||
tmp_p = sp(tmp_sp);
|
||||
tmp_p = ip(tmp_v.begin());
|
||||
tmp_p = mip(tmp_m.begin());
|
||||
tmp_p = ppi(std::pair<P, size_t>(P(), 0));
|
||||
tmp_p = spip(tmp_spip);
|
||||
tmp_p = sppi(tmp_sppi);
|
||||
tmp_p = scpip(tmp_scpip);
|
||||
tmp_p = scppi(tmp_scppi);
|
||||
|
||||
//index::translator::def<int> d; // error
|
||||
//index::translator::def< model::segment<P> > d; // error
|
||||
|
||||
index::translator::def< std::pair<model::polygon<P>, B> > d;
|
||||
index::translator::def< std::pair<B, model::polygon<P> > > dd;
|
||||
|
||||
B tmp_b;
|
||||
tmp_b = d( std::pair<model::polygon<P>, B>() );
|
||||
tmp_b = dd( std::pair<B, model::polygon<P> >() );
|
||||
}
|
||||
|
||||
#endif // TESTS_TRANSLATORS_HPP
|
||||
Reference in New Issue
Block a user