Skip to content

Instantly share code, notes, and snippets.

@weidenrinde
Forked from logc/main.cpp
Last active May 30, 2022 15:12
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save weidenrinde/89e835611721f0c1d907 to your computer and use it in GitHub Desktop.
Save weidenrinde/89e835611721f0c1d907 to your computer and use it in GitHub Desktop.
/*
Sample Results:
inserting: 6.18748
query without box: 0.0735919
query with box: 1.4e-07
POINT(4 4) - 4000
POINT(5 5) - 5000
POINT(6 6) - 6000
*/
#include <ctime>
#include <iostream>
#include <boost/foreach.hpp>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/index/rtree.hpp>
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
typedef bg::model::point<float, 2, bg::cs::cartesian> point;
typedef bg::model::box<point> box;
typedef std::pair<point, unsigned> value;
int main(int argc, char *argv[])
{
bgi::rtree< value, bgi::quadratic<16> > rtree;
auto startup = std::clock();
const int N = 100;
const int M = 10000000;
// create some values
for ( unsigned i = 0 ; i < M ; ++i )
{
point p = point(i, i);
rtree.insert(std::make_pair(p, i*1000));
}
// search for nearest neighbours
std::vector<value> returned_values;
point sought(5, 5);
box query_box(point(5 - 2, 5 - 2), point(5 + 2, 5 + 2));
std::cout << "inserting: " << double(std::clock() - startup)/CLOCKS_PER_SEC << std::endl;
startup = std::clock();
for ( unsigned i = 0; i < N ; ++i )
{
returned_values.clear();
rtree.query(bgi::satisfies([&](value const& v) {return bg::distance(v.first, sought) < 2;}),
std::back_inserter(returned_values));
}
std::cout << "query without box: " << double(std::clock() - startup)/CLOCKS_PER_SEC/N << std::endl;
startup = std::clock();
for ( unsigned i = 0; i < N ; ++i )
{
returned_values.clear();
rtree.query(
bgi::within(query_box) &&
bgi::satisfies([&](value const& v) {return bg::distance(v.first, sought) < 2;}),
std::back_inserter(returned_values));
}
std::cout << "query with box: " << double(std::clock() - startup)/CLOCKS_PER_SEC/N << std::endl;
// print returned values
BOOST_FOREACH(value const& v, returned_values)
std::cout << bg::wkt<point>(v.first) << " - " << v.second << std::endl;
return 0;
}
@awulkiew
Copy link

If you're curious about the difference in performance of both queries. The query using only the satisfies() predicate is much slower because without the within() predicate all values stored in the rtree are tested. Without spatial or nearest predicate the query should take more or less the same ammount of time as if the values were just stored in a STL container like std::vector and e.g. searched with std::find_if().

@constantinpape
Copy link

I have tried compiling this in boost 1.66.0, however I needed to change
https://gist.github.com/weidenrinde/89e835611721f0c1d907#file-main-cpp-L67
to the lambda accepting point, not value (and then in distance just v instead of v.first).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment