// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.SpatialIndex - rtree leaf implementation // // Copyright 2008 Federico J. Fernandez. // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_LEAF_HPP #define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_LEAF_HPP #include #include // TODO: Remove if print() is removed #include #include #include #include #include #include #include #include namespace boost { namespace geometry { namespace index { template class rtree_leaf : public rtree_node { public: /// container type for the leaves typedef std::shared_ptr > node_pointer; typedef std::vector > leaf_map; /** * \brief Creates an empty leaf */ inline rtree_leaf() { } /** * \brief Creates a new leaf, with 'parent' as parent */ inline rtree_leaf(node_pointer const& parent) : rtree_node (parent, 0) { } /** * \brief Search for elements in 'box' in the Rtree. Add them to 'result'. * If exact_match is true only return the elements having as * key the 'box'. Otherwise return everything inside 'box'. */ virtual void find(Box const& box, std::deque& result, bool const exact_match) { for (typename leaf_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it) { if (exact_match) { if (geometry::equals(it->first, box)) { result.push_back(it->second); } } else { if (is_overlapping(it->first, box)) { result.push_back(it->second); } } } } /** * \brief Compute bounding box for this leaf */ virtual Box compute_box() const { if (m_nodes.empty()) { return Box (); } Box r; geometry::assign_inverse(r); for(typename leaf_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it) { geometry::expand(r, it->first); } return r; } /** * \brief True if we are a leaf */ virtual bool is_leaf() const { return true; } /** * \brief Number of elements in the tree */ virtual unsigned int elements() const { return m_nodes.size(); } /** * \brief Insert a new element, with key 'box' and value 'v' */ virtual void insert(Box const& box, Value const& v) { m_nodes.push_back(std::make_pair(box, v)); } /** * \brief Proyect leaves of this node. */ virtual std::vector< std::pair > get_leaves() const { return m_nodes; } /** * \brief Add a new child (node) to this node */ virtual void add_node(Box const&, node_pointer const&) { // TODO: mloskot - define & use GGL exception throw std::logic_error("Can't add node to leaf node."); } /** * \brief Add a new leaf to this node */ virtual void add_value(Box const& box, Value const& v) { m_nodes.push_back(std::make_pair(box, v)); } /** * \brief Proyect value in position 'index' in the nodes container */ virtual Value get_value(unsigned int index) const { return m_nodes[index].second; } /** * \brief Box projector for leaf */ virtual Box get_box(unsigned int index) const { return m_nodes[index].first; } /** * \brief Remove value with key 'box' in this leaf */ virtual void remove(Box const& box) { for (typename leaf_map::iterator it = m_nodes.begin(); it != m_nodes.end(); ++it) { if (geometry::equals(it->first, box)) { m_nodes.erase(it); return; } } // TODO: mloskot - use GGL exception throw std::logic_error("Node not found."); } /** * \brief Remove value in this leaf */ virtual void remove(Value const& v) { for (typename leaf_map::iterator it = m_nodes.begin(); it != m_nodes.end(); ++it) { if (it->second == v) { m_nodes.erase(it); return; } } // TODO: mloskot - use GGL exception throw std::logic_error("Node not found."); } /** * \brief Proyect boxes from this node */ virtual std::vector get_boxes() const { std::vector result; for (typename leaf_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it) { result.push_back(it->first); } return result; } /** * \brief Print leaf (mainly for debug) */ virtual void print() const { std::cerr << "\t" << " --> Leaf --------" << std::endl; std::cerr << "\t" << " Size: " << m_nodes.size() << std::endl; for (typename leaf_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it) { std::cerr << "\t" << " | "; std::cerr << "( " << geometry::get (it->first) << " , " << geometry::get (it->first) << " ) x "; std::cerr << "( " << geometry::get (it->first) << " , " << geometry::get (it->first) << " )"; std::cerr << " -> "; std::cerr << it->second; std::cerr << " | " << std::endl;; } std::cerr << "\t" << " --< Leaf --------" << std::endl; } private: /// leaves of this node leaf_map m_nodes; }; }}} // namespace boost::geometry::index #endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_LEAF_HPP