📄 rtree.cc
字号:
#ifndef PTHREADS m_rwLock = false;#endif } catch (...) {#ifndef PTHREADS m_rwLock = false;#endif throw; }}void SpatialIndex::RTree::RTree::queryStrategy(IQueryStrategy& qs){#ifdef PTHREADS Tools::SharedLock lock(&m_rwLock);#else if (m_rwLock == false) m_rwLock = true; else throw Tools::ResourceLockedException("queryStrategy: cannot acquire a shared lock");#endif long next = m_rootID; bool hasNext = true; try { while (hasNext) { NodePtr n = readNode(next); qs.getNextEntry(*n, next, hasNext); }#ifndef PTHREADS m_rwLock = false;#endif } catch (...) {#ifndef PTHREADS m_rwLock = false;#endif throw; }}void SpatialIndex::RTree::RTree::getIndexProperties(Tools::PropertySet& out) const{ Tools::Variant var; // dimension var.m_varType = Tools::VT_ULONG; var.m_val.ulVal = m_dimension; out.setProperty("Dimension", var); // index capacity var.m_varType = Tools::VT_ULONG; var.m_val.ulVal = m_indexCapacity; out.setProperty("IndexCapacity", var); // leaf capacity var.m_varType = Tools::VT_ULONG; var.m_val.ulVal = m_leafCapacity; out.setProperty("LeafCapacity", var); // R-tree variant var.m_varType = Tools::VT_LONG; var.m_val.lVal = m_treeVariant; out.setProperty("TreeVariant", var); // fill factor var.m_varType = Tools::VT_DOUBLE; var.m_val.dblVal = m_fillFactor; out.setProperty("FillFactor", var); // near minimum overlap factor var.m_varType = Tools::VT_ULONG; var.m_val.ulVal = m_nearMinimumOverlapFactor; out.setProperty("NearMinimumOverlapFactor", var); // split distribution factor var.m_varType = Tools::VT_DOUBLE; var.m_val.dblVal = m_splitDistributionFactor; out.setProperty("SplitDistributionFactor", var); // reinsert factor var.m_varType = Tools::VT_DOUBLE; var.m_val.dblVal = m_reinsertFactor; out.setProperty("ReinsertFactor", var); // tight MBRs var.m_varType = Tools::VT_BOOL; var.m_val.blVal = m_bTightMBRs; out.setProperty("EnsureTightMBRs", var); // index pool capacity var.m_varType = Tools::VT_ULONG; var.m_val.ulVal = m_indexPool.getCapacity(); out.setProperty("IndexPoolCapacity", var); // leaf pool capacity var.m_varType = Tools::VT_ULONG; var.m_val.ulVal = m_leafPool.getCapacity(); out.setProperty("LeafPoolCapacity", var); // region pool capacity var.m_varType = Tools::VT_ULONG; var.m_val.ulVal = m_regionPool.getCapacity(); out.setProperty("RegionPoolCapacity", var); // point pool capacity var.m_varType = Tools::VT_ULONG; var.m_val.ulVal = m_pointPool.getCapacity(); out.setProperty("PointPoolCapacity", var);}void SpatialIndex::RTree::RTree::addCommand(ICommand* pCommand, CommandType ct){ switch (ct) { case CT_NODEREAD: m_readNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand)); break; case CT_NODEWRITE: m_writeNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand)); break; case CT_NODEDELETE: m_deleteNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand)); break; }}bool SpatialIndex::RTree::RTree::isIndexValid(){ bool ret = true; stack<ValidateEntry> st; NodePtr root = readNode(m_rootID); if (root->m_level != m_stats.m_treeHeight - 1) { std::cerr << "Invalid tree height." << std::endl; return false; } std::map<unsigned long, unsigned long> nodesInLevel; nodesInLevel.insert(std::pair<long, long>(root->m_level, 1)); ValidateEntry e(root->m_nodeMBR, root); st.push(e); while (! st.empty()) { e = st.top(); st.pop(); Region tmpRegion; tmpRegion = m_infiniteRegion; for (unsigned long cDim = 0; cDim < tmpRegion.m_dimension; cDim++) { tmpRegion.m_pLow[cDim] = std::numeric_limits<double>::max(); tmpRegion.m_pHigh[cDim] = -std::numeric_limits<double>::max(); for (unsigned long cChild = 0; cChild < e.m_pNode->m_children; cChild++) { tmpRegion.m_pLow[cDim] = std::min(tmpRegion.m_pLow[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pLow[cDim]); tmpRegion.m_pHigh[cDim] = std::max(tmpRegion.m_pHigh[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pHigh[cDim]); } } if (! (tmpRegion == e.m_pNode->m_nodeMBR)) { std::cerr << "Invalid parent information." << std::endl; ret = false; } else if (! (tmpRegion == e.m_parentMBR)) { std::cerr << "Error in parent." << std::endl; ret = false; } if (e.m_pNode->m_level != 0) { for (unsigned long cChild = 0; cChild < e.m_pNode->m_children; cChild++) { NodePtr ptrN = readNode(e.m_pNode->m_pIdentifier[cChild]); ValidateEntry tmpEntry(*(e.m_pNode->m_ptrMBR[cChild]), ptrN); std::map<unsigned long, unsigned long>::iterator itNodes = nodesInLevel.find(tmpEntry.m_pNode->m_level); if (itNodes == nodesInLevel.end()) { nodesInLevel.insert(std::pair<long, long>(tmpEntry.m_pNode->m_level, 1l)); } else { nodesInLevel[tmpEntry.m_pNode->m_level] = nodesInLevel[tmpEntry.m_pNode->m_level] + 1; } st.push(tmpEntry); } } } unsigned long nodes = 0; for (unsigned long cLevel = 0; cLevel < m_stats.m_treeHeight; cLevel++) { if (nodesInLevel[cLevel] != m_stats.m_nodesInLevel[cLevel]) { std::cerr << "Invalid nodesInLevel information." << std::endl; ret = false; } nodes += m_stats.m_nodesInLevel[cLevel]; } if (nodes != m_stats.m_nodes) { std::cerr << "Invalid number of nodes information." << std::endl; ret = false; } return ret;}void SpatialIndex::RTree::RTree::getStatistics(IStatistics** out) const{ *out = new Statistics(m_stats);}void SpatialIndex::RTree::RTree::initNew(Tools::PropertySet& ps){ Tools::Variant var; // tree variant var = ps.getProperty("TreeVariant"); if (var.m_varType != Tools::VT_EMPTY) { if ( var.m_varType != Tools::VT_LONG || (var.m_val.lVal != RV_LINEAR && var.m_val.lVal != RV_QUADRATIC && var.m_val.lVal != RV_RSTAR)) throw Tools::IllegalArgumentException("initNew: Property TreeVariant must be Tools::VT_LONG and of RTreeVariant type"); m_treeVariant = static_cast<RTreeVariant>(var.m_val.lVal); } // fill factor // it cannot be larger than 50%, since linear and quadratic split algorithms // require assigning to both nodes the same number of entries. var = ps.getProperty("FillFactor"); if (var.m_varType != Tools::VT_EMPTY) { if ( var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || ((m_treeVariant == RV_LINEAR || m_treeVariant == RV_QUADRATIC) && var.m_val.dblVal > 0.5) || var.m_val.dblVal >= 1.0) throw Tools::IllegalArgumentException("initNew: Property FillFactor must be Tools::VT_DOUBLE and in (0.0, 1.0) for RSTAR, (0.0, 0.5) for LINEAR and QUADRATIC"); m_fillFactor = var.m_val.dblVal; } // index capacity var = ps.getProperty("IndexCapacity"); if (var.m_varType != Tools::VT_EMPTY) { if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 4) throw Tools::IllegalArgumentException("initNew: Property IndexCapacity must be Tools::VT_ULONG and >= 4"); m_indexCapacity = var.m_val.ulVal; } // leaf capacity var = ps.getProperty("LeafCapacity"); if (var.m_varType != Tools::VT_EMPTY) { if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 4) throw Tools::IllegalArgumentException("initNew: Property LeafCapacity must be Tools::VT_ULONG and >= 4"); m_leafCapacity = var.m_val.ulVal; } // near minimum overlap factor var = ps.getProperty("NearMinimumOverlapFactor"); if (var.m_varType != Tools::VT_EMPTY) { if ( var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 1 || var.m_val.ulVal > m_indexCapacity || var.m_val.ulVal > m_leafCapacity) throw Tools::IllegalArgumentException("initNew: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities"); m_nearMinimumOverlapFactor = var.m_val.ulVal; } // split distribution factor var = ps.getProperty("SplitDistributionFactor"); if (var.m_varType != Tools::VT_EMPTY) { if ( var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0) throw Tools::IllegalArgumentException("initNew: Property SplitDistributionFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)"); m_splitDistributionFactor = var.m_val.dblVal; } // reinsert factor var = ps.getProperty("ReinsertFactor"); if (var.m_varType != Tools::VT_EMPTY) { if ( var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0) throw Tools::IllegalArgumentException("initNew: Property ReinsertFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)"); m_reinsertFactor = var.m_val.dblVal; } // dimension var = ps.getProperty("Dimension"); if (var.m_varType != Tools::VT_EMPTY) { if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initNew: Property Dimension must be Tools::VT_ULONG"); if (var.m_val.ulVal <= 1) throw Tools::IllegalArgumentException("initNew: Property Dimension must be greater than 1"); m_dimension = var.m_val.ulVal; } // tight MBRs var = ps.getProperty("EnsureTightMBRs"); if (var.m_varType != Tools::VT_EMPTY) { if (var.m_varType != Tools::VT_BOOL) throw Tools::IllegalArgumentException("initNew: Property EnsureTightMBRs must be Tools::VT_BOOL"); m_bTightMBRs = var.m_val.blVal; } // index pool capacity var = ps.getProperty("IndexPoolCapacity"); if (var.m_varType != Tools::VT_EMPTY) { if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initNew: Property IndexPoolCapacity must be Tools::VT_ULONG"); m_indexPool.setCapacity(var.m_val.ulVal); } // leaf pool capacity var = ps.getProperty("LeafPoolCapacity"); if (var.m_varType != Tools::VT_EMPTY) { if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initNew: Property LeafPoolCapacity must be Tools::VT_ULONG"); m_leafPool.setCapacity(var.m_val.ulVal); } // region pool capacity var = ps.getProperty("RegionPoolCapacity"); if (var.m_varType != Tools::VT_EMPTY) { if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initNew: Property RegionPoolCapacity must be Tools::VT_ULONG"); m_regionPool.setCapacity(var.m_val.ulVal); } // point pool capacity var = ps.getProperty("PointPoolCapacity"); if (var.m_varType != Tools::VT_EMPTY) { if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initNew: Property PointPoolCapacity must be Tools::VT_ULONG"); m_pointPool.setCapacity(var.m_val.ulVal); } m_infiniteRegion.makeInfinite(m_dimension); m_stats.m_treeHeight = 1; m_stats.m_nodesInLevel.push_back(0); Leaf root(this, -1); m_rootID = writeNode(&root); storeHeader();}void SpatialIndex::RTree::RTree::initOld(Tools::PropertySet& ps){ loadHeader(); // only some of the properties may be changed. // the rest are just ignored. Tools::Variant var; // tree variant var = ps.getProperty("TreeVariant"); if (var.m_varType != Tools::VT_EMPTY) { if ( var.m_varType != Tools::VT_LONG || (var.m_val.lVal != RV_LINEAR && var.m_val.lVal != RV_QUADRATIC && var.m_val.lVal != RV_RSTAR)) throw Tools::IllegalArgumentException("initOld: Property TreeVariant must be Tools::VT_LONG and of RTreeVariant type"); m_treeVariant = static_cast<RTreeVariant>(var.m_val.lVal); } // near minimum overlap factor var = ps.getProperty("NearMinimumOverlapFactor"); if (var.m_varType != Tools::VT_EMPTY) { if ( var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 1 || var.m_val.ulVal > m_indexCapacity || var.m_val.ulVal > m_leafCapacity) throw Tools::IllegalArgumentException("initOld: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities"); m_nearMinimumOverlapFactor = var.m_val.ulVal; } // split distribution factor var = ps.getProperty("SplitDistributionFactor"); if (var.m_varType != Tools::VT_EMPTY) { if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0) throw Tools::IllegalArgumentException("initOld: Property SplitDistributionFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)"); m_splitDistributionFactor = var.m_val.dblVal; } // reinsert factor var = ps.getProperty("ReinsertFactor"); if (var.m_varType != Tools::VT_EMPTY) { if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0) throw Tools::IllegalArgumentException("initOld: Property ReinsertFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)"); m_reinsertFactor = var.m_val.dblVal; } // tight MBRs var = ps.getProperty("EnsureTightMBRs"); if (var.m_varType != Tools::VT_EMPTY) { if (var.m_varType != Tools::VT_BOOL) throw Tools::IllegalArgumentException("initOld: Property EnsureTightMBRs must be Tools::VT_BOOL"); m_bTightMBRs = var.m_val.blVal; } // index pool capacity var = ps.getProperty("IndexPoolCapacity"); if (var.m_varType != Tools::VT_EMPTY) { if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property IndexPoolCapacity must be Tools::VT_ULONG"); m_indexPool.setCapacity(var.m_val.ulVal); } // leaf pool capacity var = ps.getProperty("LeafPoolCapacity"); if (var.m_varType != Tools::VT_EMPTY) { if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property LeafPoolCapacity must be Tools::VT_ULONG");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -