Issue with removing points from a boost::geometry::index::rtree

微笑、不失礼 提交于 2019-12-06 06:34:20

I've looked your code over and it seems fine. You're just running into a limitation with the choosen coordinate system where your coordinate isn't fully supported (yet).

You can verify this by changing the coordinate (this renders the data a bit funny, but it's about compilation success here). See this test program that shows different, equivalent approaches to deleting items:

Live On Coliru

#include <iostream>
#include <vector>
#include <string>
#include <boost/geometry.hpp>
#include <boost/geometry/io/io.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/index/distance_predicates.hpp>
#include <boost/geometry/index/predicates.hpp>
#include <boost/geometry/index/rtree.hpp>

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

//typedef bgm::point<float, 2, bg::cs::spherical_equatorial<bg::degree> > Point;
typedef bgm::point<float, 2, bg::cs::cartesian> Point;
typedef bgm::box<Point> Box;
typedef std::pair<Box, int> BoxIdPair;

int main() {
    using Tree = bgi::rtree<BoxIdPair, bgi::rstar<16> >;
    Tree tree;

    // Some tree filling code excised from here for the sake of a minimal example.
    tree.insert({ { Point(24,  19), Point(35,  26) }, 100 });
    tree.insert({ { Point(41, 112), Point(54, 148) }, 150 });
    tree.insert({ { Point(34,  24), Point(36, 100) },  92 });
    tree.insert({ { Point(21,   8), Point(43,  15) },   8 });

    while (!tree.empty()) {
        std::cout << "Tree contains " << tree.size() << " box-id values." << std::endl;
        // 1. Choose arbitrary BoxIdPair to be the leader of a new canopy.
        //    Remove it from the tree. Insert it into the canopy map, with its
        //    corresponding id.
        Point origin(0.0, 0.0);

        auto first = bgi::qbegin(tree, bgi::nearest(origin, 1)), 
             last  = bgi::qend(tree);

        if (first != last) {
            tree.remove(*first); // assuming single result
        }
    }
    std::cout << "Tree emptied\n";
}

Note Don't use the iterator-based remove() with iterators into the same rtree because remove() may invalidate them.

Note All of the remove() overloads end up deferring to raw_remove internally.

I'm not completely sure why it's not working. It appears that a trait that determines whether an index operation is interruptible is not defined for this particular combinarion of Geometries.

Update Thanks to Adam's comment below we know that it is because internally within() is used to decide which node should be checked during the tree traversal. And within(box, box) is currently not implemented for non-cartesian coordinate systems.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!