在将元素插入 boost::geometry::index::rtree 时获取“可索引无效”

Posted

技术标签:

【中文标题】在将元素插入 boost::geometry::index::rtree 时获取“可索引无效”【英文标题】:Getting "Indexable is invalid" while inserting element into boost::geometry::index::rtree 【发布时间】:2015-05-30 11:02:32 【问题描述】:

我正在初始化我的 rtree

namespace boostGEO = boost::geometry;
typedef boostGEO::model::point<double, 2, boostGEO::cs::cartesian> point;
typedef boostGEO::model::box<point> box;
typedef std::pair<box, std::pair<int, int>> edgesValue;
boostGEO::index::rtree< edgesValue, boostGEO::index::rstar<16> > tree();

然后我像这样填充它

for( int i = 0; i < items.size(); i++ )

    Item* item = items.at(i);
    std::vector<ItemRelation> relations = item->getRelations();

    point ps1( item->x, item->y );
    Item* relatedItem;
    for( int j = 0; j < relations.size(); j++ )
    
        relatedItem = relations.at(j);
        point ps2( relatedItem->x, relatedItem->y );
        box bounds( ps1, ps2 );
        edgesTree.insert( std::make_pair( bounds, std::make_pair(item->id, relatedItem->id) ) );
    

Item->x 和 Item->y 是双精度数,而 Item->id 是整数。 当我运行我的代码时,我收到以下错误:

/opt/bp/boost_1_58_0/boost/geometry/index/rtree.hpp:1248: void boost::geometry::index::rtree<Value, Options, IndexableGetter, EqualTo, Allocator>::raw_insert(const value_type&) [with Value = std::pair<boost::geometry::model::box<boost::geometry::model::point<double, 2ul, boost::geometry::cs::cartesian> >, std::pair<int, int> >; Parameters = boost::geometry::index::rstar<16ul>; IndexableGetter = boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<double, 2ul, boost::geometry::cs::cartesian> >, std::pair<int, int> > >; EqualTo = boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<double, 2ul, boost::geometry::cs::cartesian> >, std::pair<int, int> > >; Allocator = std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<double, 2ul, boost::geometry::cs::cartesian> >, std::pair<int, int> > >; boost::geometry::index::rtree<Value, Options, IndexableGetter, EqualTo, Allocator>::value_type = std::pair<boost::geometry::model::box<boost::geometry::model::point<double, 2ul, boost::geometry::cs::cartesian> >, std::pair<int, int> >]: Assertion `(detail::is_valid(m_members.translator()(value)))&&("Indexable is invalid")' failed.

谁能给我一个提示出了什么问题?我完全不知道。

【问题讨论】:

我无法从中做出正面或反面。 ItemRelation 现在是 Item 的子类吗? 哦,我的错。 ItemRelation=Item*,就像您在下面的代码示例中猜到的那样。对不起。 【参考方案1】:

你是说

boostGEO::index::rtree<edgesValue, boostGEO::index::rstar<16> > tree;

(注意缺少的括号?)。另见Most vexing parse: why doesn't A a(()); work?


除此之外,我没有看到这样的问题:

Live On Coliru

#include <boost/geometry.hpp>
#include <boost/geometry/geometry.hpp>
#include <string>

using namespace boost;
namespace boostGEO = boost::geometry;
typedef boostGEO::model::point<double, 2, boostGEO::cs::cartesian> point;
typedef boostGEO::model::box<point> box;
typedef std::pair<box, std::pair<int, int> > edgesValue;

struct Item;
using ItemRelation = Item*;

struct Item 
    double x, y;
    int id;
    std::vector<ItemRelation> _rel;
    std::vector<ItemRelation> getRelations() const  return ; 
;

int main() 
    Item item1   1, 2, 1,  ,
         item2   1, 4, 2,  ,
         item3   1, 6, 2,  ,
         item4   2, 1, 4,  ,
         item5   2, 3, 5,  ,
         item6   2, 5, 5,  ;

    std::vector<Item*> items  &item1, &item2, &item3, &item4, &item5, &item6, ;

    item3._rel =  &item1, &item2 ;
    item6._rel =  &item4, &item5 ;

    boostGEO::index::rtree<edgesValue, boostGEO::index::rstar<16> > edgesTree;

    for (size_t i = 0; i < items.size(); i++) 
        Item *item = items.at(i);
        std::vector<ItemRelation> relations = item->getRelations();

        point ps1(item->x, item->y);
        Item *relatedItem;
        for (size_t j = 0; j < relations.size(); j++) 
            relatedItem = relations.at(j);
            point ps2(relatedItem->x, relatedItem->y);
            box bounds(ps1, ps2);
            edgesTree.insert(std::make_pair(bounds, std::make_pair(item->id, relatedItem->id)));
        
    

【讨论】:

这与缺少括号无关。我不小心将它们添加到我的代码示例中。问题仍然存在。 第一项插入正确。插入第二个时发生错误。 @Lars 显示的代码运行。它正在插入 6 个项目。你可以看到它在现场运行。请使用它来发现相关差异。【参考方案2】:

断言失败通知您尝试插入的值的边界无效。也就是说,对于某些维度,Box 的最大坐标小于最小坐标。您可以在将新值插入 rtree 之前检查它:

if (bg::get<0>(ps1) > bg::get<0>(ps2) || bg::get<1>(ps1) > bg::get<1>(ps2))

    std::cerr << "invalid bounds" << std::endl;
    continue;

为了将来,您应该学习如何调试您的程序。调试器将在断言失败的地方停止。您可以使用调用堆栈进入main 函数中的rtree::insert 调用。然后您将能够看到您实际尝试插入到 rtree 中的内容。

【讨论】:

以上是关于在将元素插入 boost::geometry::index::rtree 时获取“可索引无效”的主要内容,如果未能解决你的问题,请参考以下文章

排序算法2--插入排序--折半插入排序

排序--插入

折半插入排序算法

为啥在将 bigint 数插入 bigint 列时出现算术溢出错误?

在将数据插入 Oracle 表时查找重复行

在将数据插入书籍表时选择类别和子类别