⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtree.cc

📁 一个非常好的GIS开源新版本
💻 CC
📖 第 1 页 / 共 3 页
字号:
		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("initOld: 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("initOld: Property PointPoolCapacity must be Tools::VT_ULONG");		m_pointPool.setCapacity(var.m_val.ulVal);	}	m_infiniteRegion.makeInfinite(m_dimension);}void SpatialIndex::RTree::RTree::storeHeader(){	const long headerSize =		sizeof(long) +							// m_rootID		sizeof(long) +							// m_treeVariant		sizeof(double) +						// m_fillFactor		sizeof(unsigned long) +					// m_indexCapacity		sizeof(unsigned long) +					// m_leafCapacity		sizeof(unsigned long) +					// m_nearMinimumOverlapFactor		sizeof(double) +						// m_splitDistributionFactor		sizeof(double) +						// m_reinsertFactor		sizeof(unsigned long) +					// m_dimension		sizeof(char) +							// m_bTightMBRs		sizeof(unsigned long) +					// m_stats.m_nodes		sizeof(unsigned long) +					// m_stats.m_data		sizeof(unsigned long) +					// m_stats.m_treeHeight		m_stats.m_treeHeight * sizeof(unsigned long); // m_stats.m_nodesInLevel	byte* header = new byte[headerSize];	byte* ptr = header;	memcpy(ptr, &m_rootID, sizeof(long));	ptr += sizeof(long);	memcpy(ptr, &m_treeVariant, sizeof(long));	ptr += sizeof(long);	memcpy(ptr, &m_fillFactor, sizeof(double));	ptr += sizeof(double);	memcpy(ptr, &m_indexCapacity, sizeof(unsigned long));	ptr += sizeof(unsigned long);	memcpy(ptr, &m_leafCapacity, sizeof(unsigned long));	ptr += sizeof(unsigned long);	memcpy(ptr, &m_nearMinimumOverlapFactor, sizeof(unsigned long));	ptr += sizeof(unsigned long);	memcpy(ptr, &m_splitDistributionFactor, sizeof(double));	ptr += sizeof(double);	memcpy(ptr, &m_reinsertFactor, sizeof(double));	ptr += sizeof(double);	memcpy(ptr, &m_dimension, sizeof(unsigned long));	ptr += sizeof(unsigned long);	char c = (char) m_bTightMBRs;	memcpy(ptr, &c, sizeof(char));	ptr += sizeof(char);	memcpy(ptr, &(m_stats.m_nodes), sizeof(unsigned long));	ptr += sizeof(unsigned long);	memcpy(ptr, &(m_stats.m_data), sizeof(unsigned long));	ptr += sizeof(unsigned long);	memcpy(ptr, &(m_stats.m_treeHeight), sizeof(unsigned long));	ptr += sizeof(unsigned long);	for (unsigned long cLevel = 0; cLevel < m_stats.m_treeHeight; cLevel++)	{		memcpy(ptr, &(m_stats.m_nodesInLevel[cLevel]), sizeof(unsigned long));		ptr += sizeof(unsigned long);	}	assert(headerSize == (ptr - header));	m_pStorageManager->storeByteArray(m_headerID, headerSize, header);	delete[] header;}void SpatialIndex::RTree::RTree::loadHeader(){	unsigned long headerSize;	byte* header = 0;	m_pStorageManager->loadByteArray(m_headerID, headerSize, &header);	byte* ptr = header;	memcpy(&m_rootID, ptr, sizeof(long));	ptr += sizeof(long);	memcpy(&m_treeVariant, ptr, sizeof(long));	ptr += sizeof(long);	memcpy(&m_fillFactor, ptr, sizeof(double));	ptr += sizeof(double);	memcpy(&m_indexCapacity, ptr, sizeof(unsigned long));	ptr += sizeof(unsigned long);	memcpy(&m_leafCapacity, ptr, sizeof(unsigned long));	ptr += sizeof(unsigned long);	memcpy(&m_nearMinimumOverlapFactor, ptr, sizeof(unsigned long));	ptr += sizeof(unsigned long);	memcpy(&m_splitDistributionFactor, ptr, sizeof(double));	ptr += sizeof(double);	memcpy(&m_reinsertFactor, ptr, sizeof(double));	ptr += sizeof(double);	memcpy(&m_dimension, ptr, sizeof(unsigned long));	ptr += sizeof(unsigned long);	char c;	memcpy(&c, ptr, sizeof(char));	m_bTightMBRs = c!=0;	ptr += sizeof(char);	memcpy(&(m_stats.m_nodes), ptr, sizeof(unsigned long));	ptr += sizeof(unsigned long);	memcpy(&(m_stats.m_data), ptr, sizeof(unsigned long));	ptr += sizeof(unsigned long);	memcpy(&(m_stats.m_treeHeight), ptr, sizeof(unsigned long));	ptr += sizeof(unsigned long);	for (unsigned long cLevel = 0; cLevel < m_stats.m_treeHeight; cLevel++)	{		unsigned long cNodes;		memcpy(&cNodes, ptr, sizeof(unsigned long));		ptr += sizeof(unsigned long);		m_stats.m_nodesInLevel.push_back(cNodes);	}	delete[] header;}void SpatialIndex::RTree::RTree::insertData_impl(unsigned long dataLength, byte* pData, Region& mbr, long id){	assert(mbr.getDimension() == m_dimension);	stack<long> pathBuffer;	byte* overflowTable = 0;	try	{		NodePtr root = readNode(m_rootID);		overflowTable = new byte[root->m_level];		memset(overflowTable, 0, root->m_level);		NodePtr l = root->chooseSubtree(mbr, 0, pathBuffer);		if (l.get() == root.get())		{			assert(root.unique());			root.relinquish();		}		l->insertData(dataLength, pData, mbr, id, pathBuffer, overflowTable);		delete[] overflowTable;		m_stats.m_data++;	}	catch (...)	{		delete[] overflowTable;		throw;	}}void SpatialIndex::RTree::RTree::insertData_impl(unsigned long dataLength, byte* pData, Region& mbr, long id, unsigned long level, byte* overflowTable){	assert(mbr.getDimension() == m_dimension);	stack<long> pathBuffer;	NodePtr root = readNode(m_rootID);	NodePtr n = root->chooseSubtree(mbr, level, pathBuffer);	assert(n->m_level == level);	if (n.get() == root.get())	{		assert(root.unique());		root.relinquish();	}	n->insertData(dataLength, pData, mbr, id, pathBuffer, overflowTable);}bool SpatialIndex::RTree::RTree::deleteData_impl(const Region& mbr, long id){	assert(mbr.m_dimension == m_dimension);	stack<long> pathBuffer;	NodePtr root = readNode(m_rootID);	NodePtr l = root->findLeaf(mbr, id, pathBuffer);	if (l.get() == root.get())	{		assert(root.unique());		root.relinquish();	}	if (l.get() != 0)	{		Leaf* pL = static_cast<Leaf*>(l.get());		pL->deleteData(id, pathBuffer);		m_stats.m_data--;		return true;	}	return false;}long SpatialIndex::RTree::RTree::writeNode(Node* n){	byte* buffer;	unsigned long dataLength;	n->storeToByteArray(&buffer, dataLength);	long page;	if (n->m_identifier < 0) page = StorageManager::NewPage;	else page = n->m_identifier;	try	{		m_pStorageManager->storeByteArray(page, dataLength, buffer);		delete[] buffer;	}	catch (Tools::InvalidPageException& e)	{		delete[] buffer;		std::cerr << e.what() << std::endl;		//std::cerr << *this << std::endl;		throw Tools::IllegalStateException("writeNode: failed with Tools::InvalidPageException");	}	if (n->m_identifier < 0)	{		n->m_identifier = page;		m_stats.m_nodes++;#ifndef NDEBUG		try		{			m_stats.m_nodesInLevel[n->m_level] = m_stats.m_nodesInLevel.at(n->m_level) + 1;		}		catch(...)		{			throw Tools::IllegalStateException("writeNode: writing past the end of m_nodesInLevel.");		}#else		m_stats.m_nodesInLevel[n->m_level] = m_stats.m_nodesInLevel[n->m_level] + 1;#endif	}	m_stats.m_writes++;	for (unsigned long cIndex = 0; cIndex < m_writeNodeCommands.size(); cIndex++)	{		m_writeNodeCommands[cIndex]->execute(*n);	}	return page;}SpatialIndex::RTree::NodePtr SpatialIndex::RTree::RTree::readNode(unsigned long id){	unsigned long dataLength;	byte* buffer;	try	{		m_pStorageManager->loadByteArray(id, dataLength, &buffer);	}	catch (Tools::InvalidPageException& e)	{		std::cerr << e.what() << std::endl;		//std::cerr << *this << std::endl;		throw Tools::IllegalStateException("readNode: failed with Tools::InvalidPageException");	}	try	{		long nodeType;		memcpy(&nodeType, buffer, sizeof(long));		NodePtr n;		if (nodeType == PersistentIndex) n = m_indexPool.acquire();		else if (nodeType == PersistentLeaf) n = m_leafPool.acquire();		else throw Tools::IllegalStateException("readNode: failed reading the correct node type information");		if (n.get() == 0)		{			if (nodeType == PersistentIndex) n = NodePtr(new Index(this, -1, 0), &m_indexPool);			else if (nodeType == PersistentLeaf) n = NodePtr(new Leaf(this, -1), &m_leafPool);		}		//n->m_pTree = this;		n->m_identifier = id;		n->loadFromByteArray(buffer);		m_stats.m_reads++;		for (unsigned long cIndex = 0; cIndex < m_readNodeCommands.size(); cIndex++)		{			m_readNodeCommands[cIndex]->execute(*n);		}		delete[] buffer;		return n;	}	catch (...)	{		delete[] buffer;		throw;	}}void SpatialIndex::RTree::RTree::deleteNode(Node* n){	try	{		m_pStorageManager->deleteByteArray(n->m_identifier);	}	catch (Tools::InvalidPageException& e)	{		std::cerr << e.what() << std::endl;		//std::cerr << *this << std::endl;		throw Tools::IllegalStateException("deleteNode: failed with Tools::InvalidPageException");	}	m_stats.m_nodes--;	m_stats.m_nodesInLevel[n->m_level] = m_stats.m_nodesInLevel[n->m_level] - 1;	for (unsigned long cIndex = 0; cIndex < m_deleteNodeCommands.size(); cIndex++)	{		m_deleteNodeCommands[cIndex]->execute(*n);	}}void SpatialIndex::RTree::RTree::rangeQuery(RangeQueryType type, const IShape& query, IVisitor& v){#ifdef PTHREADS	Tools::SharedLock lock(&m_rwLock);#else	if (m_rwLock == false) m_rwLock = true;	else throw Tools::ResourceLockedException("rangeQuery: cannot acquire a shared lock");#endif	try	{		stack<NodePtr> st;		NodePtr root = readNode(m_rootID);		if (root->m_children > 0 && query.intersectsShape(root->m_nodeMBR)) st.push(root);		while (! st.empty())		{			NodePtr n = st.top(); st.pop();			if (n->m_level == 0)			{				v.visitNode(*n);				for (unsigned long cChild = 0; cChild < n->m_children; cChild++)				{					bool b;					if (type == ContainmentQuery) b = query.containsShape(*(n->m_ptrMBR[cChild]));					else b = query.intersectsShape(*(n->m_ptrMBR[cChild]));					if (b)					{						Data data = Data(n->m_pDataLength[cChild], n->m_pData[cChild], *(n->m_ptrMBR[cChild]), n->m_pIdentifier[cChild]);						v.visitData(data);						m_stats.m_queryResults++;					}				}			}			else			{				v.visitNode(*n);				for (unsigned long cChild = 0; cChild < n->m_children; cChild++)				{					if (query.intersectsShape(*(n->m_ptrMBR[cChild]))) st.push(readNode(n->m_pIdentifier[cChild]));				}			}		}#ifndef PTHREADS		m_rwLock = false;#endif	}	catch (...)	{#ifndef PTHREADS		m_rwLock = false;#endif		throw;	}}void SpatialIndex::RTree::RTree::selfJoinQuery(long id1, long id2, const Region& r, IVisitor& vis){	NodePtr n1 = readNode(id1);	NodePtr n2 = readNode(id2);	vis.visitNode(*n1);	vis.visitNode(*n2);	for (unsigned long cChild1 = 0; cChild1 < n1->m_children; cChild1++)	{		if (r.intersectsRegion(*(n1->m_ptrMBR[cChild1])))		{			for (unsigned long cChild2 = 0; cChild2 < n2->m_children; cChild2++)			{				if (					r.intersectsRegion(*(n2->m_ptrMBR[cChild2])) &&					n1->m_ptrMBR[cChild1]->intersectsRegion(*(n2->m_ptrMBR[cChild2])))				{					if (n1->m_level == 0)					{						if (n1->m_pIdentifier[cChild1] != n2->m_pIdentifier[cChild2])						{							assert(n2->m_level == 0);							std::vector<const IData*> v;							Data e1(n1->m_pDataLength[cChild1], n1->m_pData[cChild1], *(n1->m_ptrMBR[cChild1]), n1->m_pIdentifier[cChild1]);							Data e2(n2->m_pDataLength[cChild2], n2->m_pData[cChild2], *(n2->m_ptrMBR[cChild2]), n2->m_pIdentifier[cChild2]);							v.push_back(&e1);							v.push_back(&e2);							vis.visitData(v);						}					}					else					{						Region rr = r.getIntersectingRegion(n1->m_ptrMBR[cChild1]->getIntersectingRegion(*(n2->m_ptrMBR[cChild2])));						selfJoinQuery(n1->m_pIdentifier[cChild1], n2->m_pIdentifier[cChild2], rr, vis);					}				}			}		}	}}std::ostream& SpatialIndex::RTree::operator<<(std::ostream& os, const RTree& t){	using std::endl;	os	<< "Dimension: " << t.m_dimension << endl		<< "Fill factor: " << t.m_fillFactor << endl		<< "Index capacity: " << t.m_indexCapacity << endl		<< "Leaf capacity: " << t.m_leafCapacity << endl		<< "Tight MBRs: " << ((t.m_bTightMBRs) ? "enabled" : "disabled") << endl;	if (t.m_treeVariant == RV_RSTAR)	{		os	<< "Near minimum overlap factor: " << t.m_nearMinimumOverlapFactor << endl			<< "Reinsert factor: " << t.m_reinsertFactor << endl			<< "Split distribution factor: " << t.m_splitDistributionFactor << endl;	}	if (t.m_stats.getNumberOfNodesInLevel(0) > 0)		os	<< "Utilization: " << 100 * t.m_stats.getNumberOfData() / (t.m_stats.getNumberOfNodesInLevel(0) * t.m_leafCapacity) << "%" << endl			<< t.m_stats;	#ifndef NDEBUG	os	<< "Leaf pool hits: " << t.m_leafPool.m_hits << endl		<< "Leaf pool misses: " << t.m_leafPool.m_misses << endl		<< "Index pool hits: " << t.m_indexPool.m_hits << endl		<< "Index pool misses: " << t.m_indexPool.m_misses << endl		<< "Region pool hits: " << t.m_regionPool.m_hits << endl		<< "Region pool misses: " << t.m_regionPool.m_misses << endl		<< "Point pool hits: " << t.m_pointPool.m_hits << endl		<< "Point pool misses: " << t.m_pointPool.m_misses << endl;	#endif	return os;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -