Boost :: geometry return indices

I want to have a class that uses boost::geometry::index::rtreefor spatial indexers. This class needs to know about amplification, so I'm using something like this:

struct VeryImportantInfo
{
    ...
    float x;
    float y;
}

class Catalogue
{
    ...
public:
    std::vector<std::shared_ptr<VeryImportantInfo> > FindIn(float x1, float x2, float y1, float y2);

protected:
    using point = bg::model::point<float, 2, bg::cs::cartesian>;
    using value = std::pair<point, std::shared_ptr<VeryImportantInfo> >;
    using box = bg::model::box<point>;        

    boost::geometry::index::rtree< value, bgi::quadratic<16> > rtree;
}

std::vector<std::shared_ptr<VeryImportantInfo> > Catalogue::FindIn(float x1, float y1, float x2, float y2)
{
    box query_box(point(x1, y1), point(x2, y2));
    ???
}

I don’t know how to execute the request correctly (please do not look at this awful vector return by copy, it’s just, for example, sake). I can do it:

std::vector<std::shared_ptr<VeryImportantInfo> > Catalogue::FindIn(float x1, float y1, float x2, float y2)
{
    box query_box(point(x1, y1), point(x2, y2));
    std::vector<value> result_s;
    rtree.query(bgi::intersects(query_box), std::back_inserter(result_s));
    std::vector<std::shared_ptr<VeryImportantInfo> > results;
    results.reserve(result_s.size());
    for( auto& p : result_s)
    {
        results.emplace_back(p.second);
    }
    return results;
}

I want to know how I can get rid of the internal copy (do not return the copy results.emplace_back(p.second);- this one). Because I can have more than 10k results in result_s, and that would be a waste.

Thank!

+4
source share
1 answer

Update in comments

, . qbegin()/qend() boost::geometry::index:

std::vector<std::shared_ptr<VeryImportantInfo> > Catalogue::FindIn(float x1, float y1, float x2, float y2)
{
    box query_box(point(x1, y1), point(x2, y2));

    auto b = bgi::qbegin(rtree, bgi::intersects(query_box)), 
        e = bgi::qend(rtree);

    auto range  = boost::make_iterator_range(b, e);

    using namespace boost::adaptors;
    return boost::copy_range<std::vector<std::shared_ptr<VeryImportantInfo>>>(
            range | transformed([](value const& p) { return p.second; }));
}

, rtree, , , .


/ :


.

, value, shared_ptr, (std:: reference_wrapper), weak_ptr.

std::reference_wrapper<T>

( :)):

Live On Coliru

#include <iostream>
#include <vector>

#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/index/rtree.hpp>

namespace bg  = boost::geometry;
namespace bgi = bg::index;

struct VeryImportantInfo {
    float x;
    float y;
};

VeryImportantInfo a = { 2, 2 };
VeryImportantInfo b = { 3, 3 };
VeryImportantInfo c = { 4, 4 };

class Catalogue
{
public:
    Catalogue() {
        rtree.insert(value(point(a.x, a.y), a));
        rtree.insert(value(point(b.x, b.y), b));
        rtree.insert(value(point(c.x, c.y), c));
    }

    std::vector<std::reference_wrapper<VeryImportantInfo> > FindIn(float x1, float x2, float y1, float y2);

protected:
    using point = bg::model::point<float, 2, bg::cs::cartesian>;
    using value = std::pair<point, std::reference_wrapper<VeryImportantInfo> >;
    using box   = bg::model::box<point>;

    boost::geometry::index::rtree< value, bgi::quadratic<16> > rtree;
};

std::vector<std::reference_wrapper<VeryImportantInfo> > Catalogue::FindIn(float x1, float y1, float x2, float y2)
{
    box query_box(point(x1, y1), point(x2, y2));

    std::vector<value> result_s;
    rtree.query(bgi::intersects(query_box), std::back_inserter(result_s));

    std::vector<std::reference_wrapper<VeryImportantInfo> > results;
    results.reserve(result_s.size());

    for(auto& p : result_s) {
        results.push_back(p.second);
    }
    return results;
}

int main() {
    Catalogue cat;
    for (VeryImportantInfo& vii : cat.FindIn(1,2,3,4))
        std::cout << vii.x << ", " << vii.y << "\n";
}

std::weak_ptr<T>

weak_ptr<>. , ( ref ), .

Live On Coliru

#include <iostream>
#include <memory>
#include <vector>

#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/index/rtree.hpp>

namespace bg  = boost::geometry;
namespace bgi = bg::index;

struct VeryImportantInfo {
    float x;
    float y;
};

auto a = std::make_shared<VeryImportantInfo>(VeryImportantInfo{2, 2});
auto b = std::make_shared<VeryImportantInfo>(VeryImportantInfo{3, 3});
auto c = std::make_shared<VeryImportantInfo>(VeryImportantInfo{4, 4});

class Catalogue
{
public:
    Catalogue() {
        rtree.insert(value(point(a->x, a->y), a));
        rtree.insert(value(point(b->x, b->y), b));
        rtree.insert(value(point(c->x, c->y), c));
    }

    std::vector<std::weak_ptr<VeryImportantInfo> > FindIn(float x1, float x2, float y1, float y2);

protected:
    using point = bg::model::point<float, 2, bg::cs::cartesian>;
    using value = std::pair<point, std::shared_ptr<VeryImportantInfo> >;
    using box   = bg::model::box<point>;

    boost::geometry::index::rtree< value, bgi::quadratic<16> > rtree;
};

std::vector<std::weak_ptr<VeryImportantInfo> > Catalogue::FindIn(float x1, float y1, float x2, float y2)
{
    box query_box(point(x1, y1), point(x2, y2));

    std::vector<value> result_s;
    rtree.query(bgi::intersects(query_box), std::back_inserter(result_s));

    std::vector<std::weak_ptr<VeryImportantInfo> > results;
    results.reserve(result_s.size());

    for(auto& p : result_s) {
        results.push_back(p.second);
    }
    return results;
}

int main() {
    Catalogue cat;
    for (auto& vii_p : cat.FindIn(1,2,3,4))
        if (auto vii = vii_p.lock())
            std::cout << vii->x << ", " << vii->y << "\n";
}
+1
source

All Articles