EVOLUTION-MANAGER
Edit File: SortedPackedIntervalRTree.cpp
/********************************************************************** * * GEOS - Geometry Engine Open Source * http://geos.osgeo.org * * Copyright (C) 2001-2002 Vivid Solutions Inc. * * This is free software; you can redistribute and/or modify it under * the terms of the GNU Lesser General Public Licence as published * by the Free Software Foundation. * See the COPYING file for more information. * **********************************************************************/ #include <geos/index/intervalrtree/SortedPackedIntervalRTree.h> #include <geos/index/intervalrtree/IntervalRTreeNode.h> #include <geos/index/intervalrtree/IntervalRTreeLeafNode.h> #include <geos/index/intervalrtree/IntervalRTreeBranchNode.h> #include <geos/index/ItemVisitor.h> #include <geos/util/UnsupportedOperationException.h> #include <algorithm> #ifdef _MSC_VER #pragma warning(disable : 4127) #endif namespace geos { namespace index { namespace intervalrtree { // // private: // void SortedPackedIntervalRTree::init() { // Already built if(root != nullptr) return; /** * if leaves is empty then nothing has been inserted. * In this case it is safe to leave the tree in an open state */ if (leaves.empty()) return; root = buildTree(); } const IntervalRTreeNode* SortedPackedIntervalRTree::buildTree() { branches.reserve(leaves.size() - 1); // now group nodes into blocks of two and build tree up recursively std::vector<const IntervalRTreeNode*> src{leaves.size()}; std::vector<const IntervalRTreeNode*> dest; std::transform(leaves.begin(), leaves.end(), src.begin(), [](const IntervalRTreeLeafNode & n) { return &n; }); // sort the leaf nodes std::sort(src.begin(), src.end(), IntervalRTreeNode::compare); while(true) { buildLevel(src, dest); if(dest.size() == 1) { return dest[0]; } std::swap(src, dest); } } void SortedPackedIntervalRTree::buildLevel(IntervalRTreeNode::ConstVect& src, IntervalRTreeNode::ConstVect& dest) { level++; dest.clear(); for(size_t i = 0, ni = src.size(); i < ni; i += 2) { const IntervalRTreeNode* n1 = src[i]; if(i + 1 < ni) { const IntervalRTreeNode* n2 = src[i + 1]; branches.emplace_back(n1, n2); dest.push_back(&branches.back()); } else { dest.push_back(n1); } } } // // protected: // // // public: // void SortedPackedIntervalRTree::insert(double min, double max, void* item) { if(root != nullptr) { throw util::UnsupportedOperationException("Index cannot be added to once it has been queried"); } leaves.emplace_back(min, max, item); } void SortedPackedIntervalRTree::query(double min, double max, index::ItemVisitor* visitor) { init(); // if root is null tree must be empty if (root == nullptr) return; root->query(min, max, visitor); } } // geos::intervalrtree } // geos::index } // geos