c++ - 使用空间索引库批量加载 R* 树

标签 c++ spatial bulk-load r-tree libspatialindex

在使用空间库逐一插入记录成功构建 R* 树 250 万次后,我尝试使用批量加载创建 R* 树。我实现了 DBStream 类以迭代方式将数据提供给 BulkLoader。本质上,它调用以下方法并为 Bulkloader 准备一个 Data(代码中的 d 变量)对象:

void DBStream::retrieveTuple() {
if (query.next()) {
    hasNextBool = true;

    int gid = query.value(0).toInt();

            // allocate memory for bounding box
            // this streets[gid].first returns bbox[4]
    double* bbox = streets[gid].first;

            // filling the bounding box values
    bbox[0] = query.value(1).toDouble();
    bbox[1] = query.value(2).toDouble();
    bbox[2] = query.value(3).toDouble();
    bbox[3] = query.value(4).toDouble();

    rowId++;

    r = new SpatialIndex::Region();
    d = new SpatialIndex::RTree::Data((size_t) 0, (byte*) 0, *r, gid);
    r->m_dimension = 2;
    d->m_pData = 0;
    d->m_dataLength = 0;

    r->m_pLow = bbox;
    r->m_pHigh = bbox + 2;
    d->m_id = gid;
} else {
    d = 0;
    hasNextBool = false;
    cout << "stream is finished d:" << d << endl;
}
}

我通过以下方式初始化 DBStream 对象并调用批量加载:

// creating a main memory RTree
memStorage = StorageManager::createNewMemoryStorageManager();

size_t capacity = 1000;
bool bWriteThrough = false;
fileInMem = StorageManager
   ::createNewRandomEvictionsBuffer(*memStorage, capacity, bWriteThrough);

double fillFactor = 0.7;
size_t indexCapacity = 100;
size_t leafCapacity = 100;
size_t dimension = 2;
RTree::RTreeVariant rv = RTree::RV_RSTAR;

DBStream dstream();

tree = RTree::createAndBulkLoadNewRTree(SpatialIndex::RTree::BLM_STR, dstream,
   *fileInMem,
   fillFactor, indexCapacity,
   leafCapacity, dimension, rv, indexIdentifier);

cout << "BulkLoading done" << endl;

批量加载调用我的 next() 和 hasNext() 函数,检索我的数据,对其进行排序,然后在构建阶段分割错误。任何线索方式?是的,错误是:

    RTree::BulkLoader: Building level 0
    terminate called after throwing an instance of 'Tools::IllegalArgumentException'

最佳答案

问题据推测出在内存分配和代码中的一些错误(也与内存分配有些相关)。首先需要正确分配数据变量的属性:

memcpy(data->m_region.m_pLow, bbox, 2 * sizeof(double));
memcpy(data->m_region.m_pHigh, bbox + 2, 2 * sizeof(double));
data->m_id = gid;

其次(也是最重要的)getNext 必须返回一个包含所有值的新对象:

RTree::Data *p = new RTree::Data(returnData->m_dataLength, returnData->m_pData,
returnData->m_region, returnData->m_id);
return returnData;

内存的重新分配由 RTree 完成,因此无需特别注意。

关于c++ - 使用空间索引库批量加载 R* 树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13135026/

相关文章:

Django bulk_create 忽略导致 IntegrityError 的行?

c++ - 根据我的测试,[更有效的 C++] 中的第 3 项似乎无效

c++ - 现实中如何在 Visual Studio 中使用 vcpkg 安装包?

r - 如何将多边形修改为孔(SpatialPolygons)并更改其槽

r - 映射澳大利亚城市 - R 空间

sql - 在 Oracle 中 10 分钟内插入 1000 万个查询?

c++ - 如何标记一个区域以使 clang-format 不会触及它?

c# - glBufferData 总是因 GL_INVALID_ENUM 而失败,即使它不应该

MySQL Spatial CONTAINS 显示错误结果

hadoop - 异常:org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.AccessControlException):权限被拒绝:user = hbase,access = EXECUTE